Я использовал ClientBase для использования WCF для подключения к службе. Затем я вызываю метод на канале для связи с сервисом.
base.Channel.CalculateSomething();
Является ли этот поток потоков безопасным или я должен блокировать его при запуске нескольких потоков?
Спасибо
Ответ 1
Последующие комментарии к ответам здесь также меня не совсем поняли, поэтому я сделал еще несколько копаний. Вот несколько убедительных доказательств того, что ClientBase<T>
является потокобезопасным - этот пост в блоге обсуждает, как заставить службу WCF правильно работать в присутствии одного клиентского прокси-сервера несколькими потоками одновременно (смелый акцент делается на оригинале):
... Однако существует сценарий, в котором установка ConcurrencyMode to Multiple в службе PerCall может увеличить пропускную способность вашей службы, если применяются следующие условия:
-
Клиент является многопоточным и выполняет вызовы вашей службы из нескольких потоков с использованием того же прокси-сервера.
-
Связывание между клиентом и службой привязка, имеющая сеанс (например, netTcpBinding, wsHttpBinding с надежным сеансом, netNamedPipeBinding и т.д.).
Кроме того, доказательства в этом сообщении, похоже, противоречат дополнительному замечанию Брайана о том, что WCF выполняет сериализацию любых многопоточных запросов. Сообщение показывает несколько запросов от одного клиента, работающего одновременно - , если ConcurrencyMode.Multiple
и InstanceContextMode.PerCall
.
Ниже приведено дополнительное обсуждение относительно последствий этого подхода, а также некоторых альтернатив.
Ответ 2
Да, это поточно-безопасный. Однако вы должны знать, что WCF автоматически сериализует выполнение CalculateSomething
, когда он вызывается из более чем одного потока, используя тот же экземпляр ClientBase
. Поэтому, если вы ожидали, что CalculateSomething
будет выполняться одновременно, вам придется переосмыслить свой дизайн. Посмотрите этот ответ для одного подхода к созданию асинхронного API для метода CalculateSomething
.
Ответ 3
Да, вызов метода на канале является потокобезопасным (с точки зрения клиента - перспектива обслуживания зависит от реализации сервиса). Вы можете вызвать этот метод из нескольких потоков параллельно. Даже автогенерирующий прокси предложит вам создавать методы для асинхронных вызовов.
Ответ 4
Кому это может быть интересно.
Клиентская база 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
Имя: Объект один "Привет"