WCF InstanceContextMode. Несколько проблем
Итак, я размещаю службу WCF в приложении WinForms. У меня есть следующие
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerCall)]
public class Test : ITest
{
public string TestIt(string input)
{
Thread.Sleep(5000);
return "test";
}
}
Я использую именованные каналы и имею два экземпляра другого приложения, которые действуют как клиенты для указанной выше службы WCF (работающей в приложении WinForms). Я подумал, основываясь на настройке ConcurrencyMode для Multiple, что, когда Client1 вызывает тестовую службу, Client2 не должен ждать завершения первого вызова. Однако, когда Client1 вызывает TestIt, Client2 блокируется до тех пор, пока вызов от Client1 не будет завершен!?!?! Разве он не должен каждый раз создавать новый экземпляр на основе вышеуказанных настроек?
Кроме того, лучший способ сохранить работоспособность приложения WinForms, в котором размещена служба WCF, - это запустить службу WCF в отдельном потоке?
ПРИМЕЧАНИЕ. Установка [CallbackBehavior (UseSynchronizationContext = false)] в классе Test не устраняет проблему. Служба по-прежнему отвечает только на один запрос за раз.
Ответов (3)3
У меня такая же проблема.
Мой класс, реализующий обратный вызов, также содержал методы для клиента wcf, поэтому, когда я вызывал какой-то метод из удаленной службы, а служба вызывала метод обратного вызова, я создавал тупик.
[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
}
}