WCF ClientBase线程安全吗?

问题描述 投票:30回答:4

我已经实现了ClientBase以使用WCF连接到服务。然后,我在通道上调用一种方法与服务进行通信。

base.Channel.CalculateSomething();

这个调用线程是安全的还是应该在运行多个线程时锁定它?

谢谢

multithreading wcf
4个回答
15
投票

对这里答案的后续评论也让我不确定,所以我做了一些挖掘。以下是ClientBase<T>是线程安全的一些确凿证据 - this blog post讨论了如何在多个线程同时使用单个客户端代理的情况下使WCF服务正常执行(大胆强调在原始版本中):

...但是,如果满足以下条件,则可能会在PerCall服务上将ConcurrencyMode设置为Multiple可以增加服务的吞吐量:

  1. 客户端是多线程的,并使用相同的代理从多个线程调用您的服务。
  2. 客户端和服务之间的绑定是具有会话的绑定(例如,netTcpBinding,wsHttpBinding w / Reliable Session,netNamedPipeBinding等)。

此外,这篇文章中的证据似乎与Brian的额外评论相矛盾,即WCF序列化任何多线程请求。该帖子显示了同时运行的单个客户端的多个请求 - 如果使用ConcurrencyMode.MultipleInstanceContextMode.PerCall

关于这种方法的性能影响以及一些替代方案,还有一些额外的讨论here


12
投票

是的,它是线程安全的。但是,您应该知道,当使用相同的CalculateSomething实例从多个线程调用时,WCF将自动序列化ClientBase的执行。因此,如果您期望CalculateSomething同时运行,那么您将不得不重新考虑您的设计。查看this answer,了解为CalculateSomething方法创建异步API的一种方法。


3
投票

是调用通道上的方法是线程安全的(从客户端角度来看 - 服务角度取决于服务实现)。您可以并行地从多个线程调用此方法。甚至自动生成代理也可以为异步调用创建方法。


0
投票

敬启者。 WCF客户端基本可以是线程安全的,至少在此配置中是这样。我没有尝试其他配置。

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

服务:

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

客户:

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;
    }
    );
}

结果:

任务1开始:15:47:08 任务2开始:15:47:10

任务1完成:15:47:18 名称:对象一“你好”

任务2完成:15:47:20 名称:对象一“你好”

© www.soinside.com 2019 - 2024. All rights reserved.