Я столкнулся с проблемой со службой WCF, которая вызывает метод обратного вызова на клиенте.Сначала служба:
[ServiceContract(
SessionMode = SessionMode.Required,
CallbackContract = typeof(IMarketObserver))]
public interface IServer
{
...
[OperationContract]
[FaultContractAttribute(typeof(WCFFaultDetail))]
bool NotifyOnMarket(EnumMarkets marketID);
...
}
Реализация службы:
[ServiceBehavior(
InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple,
UseSynchronizationContext = false)]
public sealed class Platform : IServer
{
...
public bool NotifyOnMarket(EnumMarkets marketID)
{
try
{
IMarketObserver callback = OperationContext.Current.GetCallbackChannel<IMarketObserver>();
if (subscribers.Contains(callback) == false)
{
subscribers.Add(callback);
}
}
catch
{
return false;
}
//This call may cause a call to the callback method SendMarketData()!!
callSomeMethod();
return exchangeProxy.IsMarketIDValid();
}
Контракт обратного вызова:
public interface IMarketObserver
{
[OperationContract(IsOneWay = true)]
void SendMarketData(MarketData marketData);
}
Клиентская реализация этого обратного вызова:
[CallbackBehavior(
ConcurrencyMode = ConcurrencyMode.Multiple,
UseSynchronizationContext = false)]
public class MarketBase :
IServerCallback
{
protected IService serviceProxy;
public void SendMarketData(MarketData marketData)
{
//Do something
}
private void NotifyOnMarkets()
{
foreach (EnumMarkets item in observedMarkets)
{
try
{
bool res = serviceProxy.NotifyOnMarket(item);
}
catch (Exception e)
{
...
}
}
}
Проблема возникает при вызове NotifyOnMarkets () с циклом foreach.
Если в списке наблюдаемых маркеров есть только один элемент, то есть точно один метод метода NotifyOnMarket () службы и всеработает нормально.
Но если наблюдаемый рынок содержит более одного элемента, то NotifyOnMarket () будет вызываться много раз с высокой частотой для сервера.
Реализация NotifyOnMarket () на серверевызывает метод, который, в свою очередь, вызывает метод обратного вызова SendMarketData (я прокомментировал этот факт).
В следах я вижу, что serviceProxy.NotifyOnMarket (item);не возвращает второй элемент, возникает тайм-аут.
На стороне сервера правильные обращения к NotifyOnMarket () обрабатываются правильно, и метод завершается.Но, как сказано выше, логический результат не будет отображаться на клиенте (тайм-аут).
Кроме того, можно видеть, что на стороне сервера вызывается обратный вызов (он односторонний, поэтому ответ не будетвозвращается), но на стороне клиента ничего не происходит, так как реализация обратного вызова не вызывается.
Мой вывод состоит в том, что произошла какая-то тупиковая ситуация, и это может быть связано с тем, что экземпляр клиента блокирует себя, и поэтому серверне вызывать метод обратного вызова.
Лучше ли отделить контекстный класс экземпляра от класса, который также выполняет сервисные вызовы?Если да, то почему?
Спасибо за совет,
Юрген