WCF Callback-deadlock

Rannte ich in ein problem mit einem WCF-Dienst ruft eine callback Methode auf dem client. Zuerst der service:

[ServiceContract(
SessionMode = SessionMode.Required,
CallbackContract = typeof(IMarketObserver))]
public interface IServer
{
  ...
  [OperationContract]
  [FaultContractAttribute(typeof(WCFFaultDetail))]
  bool NotifyOnMarket(EnumMarkets marketID);
  ...
}

Service-Implementierung:

[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();
}

Den rückrufvertrag:

public interface IMarketObserver
{
  [OperationContract(IsOneWay = true)]
  void SendMarketData(MarketData marketData);
}

Die client-Implementierung dieses callback ist:

[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)
          {
             ...
          }
      }
  }

Tritt das problem beim Aufruf NotifyOnMarkets() mit der foreach-Schleife.

Wenn es nur ein Element in der observedMarkets Liste, so gibt es genau einen Aufruf der service ist NotifyOnMarket () - Methode, und alles ist in Ordnung.

Aber wenn observedMarkets enthält mehr als ein Element, dann NotifyOnMarket() wird aufgerufen, viele Male mit einer hohen Frequenz auf den server.

Die Umsetzung der NotifyOnMarket() auf dem server wird eine Methode aufgerufen, die wiederum ruft dann die callback-Methode SendMarketData(ich kommentierte diese Tatsache).

In den Spuren, die ich sehen kann, dass serviceProxy.NotifyOnMarket(item); nicht zurück, auf ein zweites Element, ein timeout Auftritt.

Auf dem server der Seite, mehrere Anrufe zu NotifyOnMarket() werden korrekt behandelt und die Methode wird verlassen. Aber wie oben schon gesagt, wird das boolean-Ergebnis wird nicht zeigen, bis auf dem client(timeout).

Außerdem, kann man sehen, dass auf der server-Seite der Rückruf aufgerufen wird(es ist one-way, so dass keine Antwort wird zurückgegeben), aber auf der client-Seite geschieht nichts, da die callback-Implementierung ist nicht genannt.

Mein Fazit ist, dass irgendeine Art von deadlock aufgetreten ist und dies vielleicht aufgrund der client-Instanz, die Schlösser selbst und so kann der server nicht Aufruf der callback-Methode.

Ist es, besser zu trennen die Instanz-Kontext-Klasse von der Klasse, die auch die Durchführung von service-Aufrufe? Wenn ja, warum?

Dank für die Beratung, die

Jürgen

InformationsquelleAutor Juergen | 2011-10-31
Schreibe einen Kommentar