所以我在WinForms应用程序中托管WCF服务。我有以下
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerCall)]
public class Test : ITest
{
public string TestIt(string input)
{
Thread.Sleep(5000);
return "test";
}
}
我正在使用命名管道,并且有两个另一个应用程序的实例,它们充当上述WCF服务的客户端(在WinForms应用程序中运行)。我认为基于Multiple的ConcurrencyMode设置,当Client1调用Test Service时,Client2不必等到第一个调用完成。但是,当Client1调用TestIt时,Client2会阻塞,直到来自Client1的调用完成!?!?!根据上述设置,它不应每次都创建一个新实例吗?
此外,保持托管WCF服务响应的WinForms应用程序的最佳方法是在单独的线程上运行WCF服务吗?
注意:在Test类上设置[CallbackBehavior(UseSynchronizationContext = false)]并不能解决问题。该服务一次只响应一个请求。
答案 0 :(得分:10)
听起来你想设置这个
为假。默认情况下,如果在service.Open()发生时存在同步上下文,WCF将对其进行拾取并使用它。但是如果你不想要这个功能,这个标志就是如何关闭它。
答案 1 :(得分:4)
在深入研究之后,我能够使其正常工作的唯一方法是在WinForms应用程序中的单独线程上启动ServiceHost。如果不进行此设置,则ConcurrencyMode和InstanceContextMode属性不执行任何操作。
答案 2 :(得分:1)
我遇到了同样的问题。
我实现Callback的类也包含wcf客户端的方法,所以当我从远程服务调用某个方法并且服务调用Callback方法时,我正在创建一个死锁。
[CallbackBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class AppContext : ICustomerOrderCallback
{
//WCF Proxy client
private CustomerOrderClient _client = null;
public AppContext()
{
InstanceContext context = new InstanceContext(this);
_client = new CustomerOrderClient(context);
_client.Subscribe(); //Remote method for subscribing callback
}
public void SendMessage(string message)
{
//Calling Remote method
_client.SendMessage(message);
}
//....code
//callback method
public void OnMessageReceived(string message)
{
//.....code
}
}
所以我为回调创建了一个单独的类,为它添加了属性CallBehavior,一切正常。
public class AppContext
{
private CustomerOrderClient _client = null;
private MyCallbackClass _myCallback = null;
public AppContext()
{
_myCallback = new MyCallbackClass();
InstanceContext context = new InstanceContext(_myCallback);
_client = new CustomerOrderClient(context);
_client.Subscribe();
}
public void SendMessage(string message)
{
_client.SendMessage(message);
}
}
[CallbackBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MyCallbackClass : ICustomerOrderCallback
{
public void OnMessageReceived(string message)
{
//.....code
}
}