开发者

Pattern to properly remove WCF callbacks on failure

I've got a class that stores a static list of connection instances. On callbacks, every instance in the list is called, and if the call fails the instance is removed from the list.

Devil's in detail, since sync is needed when adding, removing and enumerating list items. I'm currently using this pattern:

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

My idea:

  1. Static list of instances, every instance stores the CB channel.
  2. Instance is removed when channel is closed or aborted.
  3. On callback a copy of the list is created (in sync) and enumerated (out of sync).
  4. When a callback fails the channel gets aborted.

A failed callback causes a channel abort, which in turn causes an Dispose and removal from th开发者_StackOverflowe list. This may or may not happen on the same thread (cannot be guaranteed since a Dispose may be raised anytime due to a different event).

My question is, is this a common pattern to handle instance storing and callback fault handling, or how could it be improved? Is copying the list before enumerating in RaiseCallback a bug, or is it correct?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜