我正在尝试设置一个简单的双工服务,客户端通过它连接到服务器。任何连接的客户端都可以执行BookAdded服务操作。当这种情况发生时,服务器应该在所有连接的客户端上引发回调,以将更改通知给它们。
回调似乎工作得很好,只是回调操作需要使用Dispatcher.BeginInvoke在UI线程上运行一些东西。
在我的例子中,Console.WriteLine("Callback thread")会被执行,但Console.WriteLine("Dispatcher thread")不会。这是什么原因呢?
我的服务合同:
public interface ICallback
{
[OperationContract(IsOneWay = true)]
void BookAdded(string bookId);
}
[ServiceContract(
CallbackContract = typeof(ICallback),
SessionMode = SessionMode.Required)]
public interface IService
{
[OperationContract]
bool BookAdded(string bookId);
}我的服务实现:
[ServiceBehavior(
UseSynchronizationContext = false,
InstanceContextMode = InstanceContextMode.PerSession,
ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class MyService : IService
{
public bool BookAdded(string bookId)
{
try
{
Console.WriteLine("Client Added Book " + bookId);
foreach (ICallback callback in connectedClients)
{
callback.BookAdded(bookId);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return true;
}
}我的客户端实现:
[CallbackBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MyCallBack: ICallback, IDisposable
{
private Dispatcher theDispatcher;
private InstanceContext context;
private WcfDuplexProxy<IService> proxy;
[ImportingConstructor]
public MyCallBack()
{
theDispatcher = Dispatcher.CurrentDispatcher;
context = new InstanceContext(this);
proxy = new WcfDuplexProxy<IService>(context);
proxy.Connect();
}
public IService Service
{
get
{
return proxy.ServiceChannel;
}
}
public void CallServiceOperation()
{
Service.BookAdded("BOOK1234");
}
public void BookAdded(string bookId)
{
Console.WriteLine("Callback thread");
theDispatcher.BeginInvoke(new Action(() => { Console.WriteLine("Dispatcher thread"); }));
}
public void Dispose()
{
Service.Disconnect();
proxy.Close();
}发布于 2012-07-20 14:42:34
我想我也遇到过类似的问题。我用一个新的线程来调用Dispatcher.beginInvoke解决了这个问题。据我所知,UI线程向Service发送请求,Service将在服务操作期间调用在您的客户端中实现的回调协定。因此,如果在回调操作中,它调用待决UI线程的控件,以等待来自Service操作的响应。这就是客户端被死锁的原因。所以你可以试试下面的代码:Thread th=new Thread(new ThreadStart(()=>{Console.WriteLine("Callback thread");
`theDispatcher.BeginInvoke(new Action(() => { Console.WriteLine("Dispatcher thread"); }));`})); th.Start();
https://stackoverflow.com/questions/5515089
复制相似问题