当调用不存在的方法时,C#Action / Delegate使wcf通道出现故障

时间:2012-09-28 15:52:50

标签: c# wcf exception delegates callback

我在wcf中有一个回调服务,如下所示:

[ServiceContract(CallbackContract = typeof(IMyCallbacks), Namespace = "MyNamespace")]
public interface IMyService
{
  [OperationContract]
  bool subscribe();

  [OperationContract]
  bool unsubscribe();
}

public interface IMyCallbacks
{
  [OperationContract(IsOneWay=true)]
  void onNewCallback(int iValue);
}

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
public class MyService : IMyService
{
    Action<int> DelegateOnNewCallback { get; set; }
    public bool subscribe()
    {
      try
      {
        var wClient = OperationContext.Current.GetCallbackChannel<IMyCallbacks>();
        DelegateOnNewCallback += wClient.onNewCallback;
      }  
      catch (Exception iEx)
      {
        Console.Writeline(iEx.Message);
        return false;
      }
      return true;
    }

    public bool unsubscribe()
    {
      try
      {
        var wClient = OperationContext.Current.GetCallbackChannel<IMyCallbacks>();
        DelegateOnNewCallback -= wClient.onNewCallback;
      }
      catch (Exception iEx)
      {
        Console.Writeline(iEx.Message);
        return false;
      }
      return true;
    }

    // This function is called really often
    public void CallingFunction(int iValue)
    {
       try
       {
         DelegateOnNewCallback(iValue);
       }
       catch (Exception ex)
       {
          Console.Writeline(ex.Message);
       }
    }
}

在客户端,加载后,我订阅回调并打印我收到的值。当客户端关闭时,我调用取消订阅方法。该服务独立于客户端,在此过程中永远不会被销毁。

当客户端进程被销毁并且未调用unsubscribe方法时遇到问题。由于Wcf通道处于故障状态,因此每个后续客户端都不会收到回调。每次调用CallingFunction时,我都会收到异常:

The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it has been Aborted.

我认为这是因为,由于未正确调用取消订阅,DelegateOnNewCallback仍会尝试调用已销毁的客户端方法,该方法现在尚未存在。 在那种特殊情况下,我希望通过我的Try / Catch收到例外,但我不希望该服务进入故障状态。

我想要的行为是,当调用CallingFunction时,它将尝试调用DelegateOnNewCallback包含的每个方法,如果方法不再存在,则从列表中静默删除它并继续调用后续方法。

我怎样才能做到这一点?

0 个答案:

没有答案