我有一个存储连接实例静态列表的类。在回调中,调用列表中的每个实例,如果调用失败,则从列表中删除实例。
恶魔的细节,因为在添加,删除和枚举列表项时需要同步。我目前正在使用这种模式:
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 ();
}
}
}
}
我的想法:
失败的回调会导致频道中止,从而导致从列表中删除和删除。这可能会也可能不会发生在同一个线程上(无法保证,因为可能会因为不同的事件而随时引发Dispose。)
我的问题是,这是处理实例存储和回调故障处理的常见模式,还是如何改进?是否在RaiseCallback枚举错误之前复制列表,或者它是否正确?