我有一个存储连接实例静态列表的类。在回调时,会调用列表中的每个实例,如果调用失败,则会从列表中删除该实例。
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 ();
}
}
}
}
我的想法:
-
实例的静态列表,每个实例存储CB通道。
-
-
在回调时,将创建(同步)和枚举(不同步)列表的副本。
-
失败的回调会导致通道中止,进而导致从列表中释放和删除。这可能发生,也可能不发生在同一个线程上(无法保证,因为由于不同的事件,释放可能随时引发)。
我的问题是,这是处理实例存储和回调错误处理的常见模式,还是如何改进它?在用RaiseCallback枚举之前复制列表是一个错误还是正确的?