Я пытаюсь настроить простой дуплексный сервис, при котором клиенты подключаются к серверу.Любой подключенный клиент может выполнить операцию службы BookAdded
.Когда это происходит, сервер должен вызвать обратный вызов на всех подключенных клиентах, чтобы уведомить их об изменении.
Кажется, что обратный вызов работает нормально, за исключением того, что для операции обратного вызова необходимо выполнить что-то в потоке пользовательского интерфейса, используя1004 *.
В моем случае 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();
}