Frage

Can someone explain the issues that although I set both the InstanceContextMode and ConcurrencyMode to single with max concurrent calls instances and sessions set to 1 in ServiceThrottlingBehavior, I still found that at least 2 threads are processing the wcf requests?

Client Output:

Client name :kk Instance:1 Thread:13 Time:2013/12/30 12:17:56
Client name :kk Instance:1 Thread:12 Time:2013/12/30 12:17:57
Client name :kk Instance:1 Thread:13 Time:2013/12/30 12:17:58

Server Code:

    Uri httpUrl = new Uri("http://localhost:8010/MyService/HelloWorld");

    //Create ServiceHost
    ServiceHost host
    = new ServiceHost(typeof(ClassLibrary1.HelloWorldService), httpUrl);

    //Add a service endpoint
    host.AddServiceEndpoint(typeof(ClassLibrary1.IHelloWorldService)
    , new WSHttpBinding(), "");

    //Enable metadata exchange
    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
    smb.HttpGetEnabled = true;
    ServiceThrottlingBehavior stb = new ServiceThrottlingBehavior
    {
        MaxConcurrentCalls = 1,
        MaxConcurrentInstances = 1 ,
        MaxConcurrentSessions = 1
    };
    host.Description.Behaviors.Add(smb);
    host.Description.Behaviors.Add(stb);
    //Start the Service
    host.Open();

Client Code:

    ServiceReference1.HelloWorldServiceClient obj = new ServiceReference1.HelloWorldServiceClient();
    for(int i=0;i<15;i++)
    {
       obj.Call(str);
       Thread.Sleep(1000);
    }

Service Code:

[ServiceContract]
public interface IHelloWorldService
{
    [OperationContract(IsOneWay=true)]
    void Call(string ClientName);
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
public class HelloWorldService : IHelloWorldService
{
    public static int i;

    public HelloWorldService()
    {
        i++;
    }
    public void Call(string ClientName)
    {
        Console.WriteLine("Client name :" + ClientName + " Instance:" + i.ToString() + " Thread:" + Thread.CurrentThread.ManagedThreadId.ToString() + " Time:" + DateTime.Now.ToString() + "\n\n");
    }

}
War es hilfreich?

Lösung

I'm not an expert on threading, but I'll take a stab at this and expand upon my comments.

According to MSDN, ConcurrencyMode.Single means The service instance is single-threaded and does not accept reentrant calls. If the InstanceContextMode property is Single, and additional messages arrive while the instance services a call, these messages must wait until the service is available or until the messages time out.

You're calling your service with a 1 second delay between each successive call. Your output shows this as well - each call is 1 second later than the immediately previous one.

I believe the thread id is a red herring in this case, as I would expect the service to use an available thread from the thread pool. I don't see anything in the documentation that guarantees the same thread will be used every time, and it seems to me that would be an unreasonable expectation.

If you're expecting a dedicated thread from the available threads, I don't think you can do that. If you're expecting the service to handle only one request at a time, the way you have it should do that.

Andere Tipps

I agree with Tim's answer that same thread need not be servicing all the calls. ConcurencyMode.Single will only guarantee one thread is servicing the call at a time.

If for some reason you require thread affinity on your WCF service, for example, if you are running a singleton service on a WinForms/WPF application and you want the service calls to run over the UI thread only - then, you just have to Open the service host on the UI thread. WCF is SynchronizationContext aware and will dispatch calls to UI thread only irrespective of what your ConcurrencyMode is. Also, see UseSynchronizationContext property of ServiceBehavior attribute.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top