Is WCF ClientBase thread safe?

前端 未结 4 1771
庸人自扰
庸人自扰 2020-12-10 10:59

I have implemented ClientBase to use WCF to connect to a service. I\'m then calling a method on the channel to communicate with the service.

base.Channel.Cal         


        
相关标签:
4条回答
  • 2020-12-10 11:10

    To Whom It May Concern. WCF Client base can be thread safe, at least in this configuration. I did not tried other configurations.

    [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IWcfCallbacksContract), Namespace = "http://wcf.applicatin.srv/namespace")]
    public interface IWcfContract
    {
        [OperationContract]
        CompositeReturnObject GetServerObject();
    }
    

    Service:

    public CompositeReturnObject GetServerObject()
    {
        CompositeReturnObject ret = new CompositeReturnObject("Hello");
        Thread.Sleep(10000); // Simulating long call
        return ret;
    }
    

    Client:

    private void GetData_Click(object sender, RoutedEventArgs e)
    {
        Console.WriteLine("Task 1 start: " + DateTime.Now.ToString("HH:mm:ss"));
    
        Task.Factory.StartNew(() => {
            var res = _proxy.GetServerObject();
            Console.WriteLine("Task 1 finish: " + DateTime.Now.ToString("HH:mm:s"));
            Console.WriteLine(res.ToString());
            return;
        }
        );
    
        Thread.Sleep(2000);
    
        Console.WriteLine("Task 2 start: " + DateTime.Now.ToString("HH:mm:ss"));
    
        Task.Factory.StartNew(() => {
            var res = _proxy.GetServerObject();
            Console.WriteLine("Task 2 finish: " + DateTime.Now.ToString("HH:mm:s"));
            Console.WriteLine(res.ToString());
            return;
        }
        );
    }
    

    And result:

    Task 1 start: 15:47:08
    Task 2 start: 15:47:10

    Task 1 finish: 15:47:18
    Name: Object one "Hello"

    Task 2 finish: 15:47:20
    Name: Object one "Hello"

    0 讨论(0)
  • 2020-12-10 11:16

    The follow-up comments on the answers here had me uncertain as well, so I did some more digging. Here is some solid evidence that ClientBase<T> is thread-safe - this blog post discusses how to make a WCF service perform properly in the presence of a single client proxy being used by multiple threads simultaneously (the bold emphasis is in the original):

    ... However, there is a scenario where setting ConcurrencyMode to Multiple on a PerCall service can increase throughput to your service if the following conditions apply:

    1. The client is multi-threaded and is making calls to your service from multiple threads using the same proxy.

    2. The binding between the client and the service is a binding that has session (for example, netTcpBinding, wsHttpBinding w/Reliable Session, netNamedPipeBinding, etc.).

    Also, the evidence in this post seems to contradict Brian's additional remark that WCF serializes any multi-threaded requests. The post shows multiple requests from a single client running simultaneously - if ConcurrencyMode.Multiple and InstanceContextMode.PerCall are used.

    There is some additional discussion here regarding the performance implications of this approach as well as some alternatives.

    0 讨论(0)
  • 2020-12-10 11:23

    Yes calling the method on the channel is thread safe (from the client perspective - service perspective depends on service implementation). You can call this method from multiple threads in parallel. Even autogenerating proxy will offer you to create methods for asynchronnous calls.

    0 讨论(0)
  • 2020-12-10 11:30

    Yes, it is thread-safe. However, you should know that WCF will automatically serialize the execution of CalculateSomething when it is called from more than one thread using the same ClientBase instance. So if you were expecting CalculateSomething to run concurrently then you will have to rethink your design. Take a look at this answer for one approach to creating an asynchronous API for the CalculateSomething method.

    0 讨论(0)
提交回复
热议问题