模式以在失败时正确删除WCF回调

时间:2010-11-08 11:14:03

标签: .net wcf design-patterns callback

我有一个存储连接实例静态列表的类。在回调中,调用列表中的每个实例,如果调用失败,则从列表中删除实例。

恶魔的细节,因为在添加,删除和枚举列表项时需要同步。我目前正在使用这种模式:

class Foo : IDisposable
{
    private static readonly List<Foo> _Connections = new List<Foo> ();
    private readonly IFooCallback CallbackChannel;

    internal Foo ()
    {
        CallbackChannel = OperationContext.Current.GetCallbackChannel<IFooCallback> ();

        lock (_Connections) {
            _Connections.Add (this);
            OperationContext.Current.Channel.Closing += (s, e) => Dispose ();
            OperationContext.Current.Channel.Faulted += (s, e) => Dispose ();
        }
    }

    public void Dispose ()
    {
        lock (_Connections) {
            _Connections.Remove (this);
        }
    }

    private void RaiseCallback ()
    {
        List<Foo> connections;
        lock (_Connections) {
            connections = new List<Foo> (_Connections);
        }
        foreach (var con in connections) {
            try {
                con.CallbackChannel.SomeCallback ();
            }
            catch (CommunicationException) {
                OperationContext.Current.Channel.Abort ();
            }
            catch (TimeoutException) {
                OperationContext.Current.Channel.Abort ();
            }
        }
    }
}

我的想法:

  1. 静态实例列表,每个实例都存储CB通道。
  2. 当频道关闭或中止时,将删除实例。
  3. 在回调时,会创建(同步)列表副本并枚举(不同步)。
  4. 当回调失败时,频道会中止。
  5. 失败的回调会导致频道中止,从而导致从列表中删除和删除。这可能会也可能不会发生在同一个线程上(无法保证,因为可能会因为不同的事件而随时引发Dispose。)

    我的问题是,这是处理实例存储和回调故障处理的常见模式,还是如何改进?是否在RaiseCallback枚举错误之前复制列表,或者它是否正确?

0 个答案:

没有答案