我有这个实现了 IDisposable
的对象 PreloadClient
,我想处理它,但是在异步方法完成它们的调用之后...这并没有发生
private void Preload(SlideHandler slide)
{
using(PreloadClient client = new PreloadClient())
{
client.PreloadCompleted += client_PreloadCompleted;
client.Preload(slide);
}
// Here client is disposed immediately
}
private void client_PreloadCompleted(object sender, SlidePreloadCompletedEventArgs e)
{
// this is method is called after a while,
// but errors are thrown when trying to access object state (fields, properties)
}
那么,有什么想法或解决办法吗??
最佳答案
您不应该使用
using
构造,而应该在不再需要时处置您的对象:// keep a list of strong references to avoid garbage collection, // and dispose them all in case we're disposing the encapsulating object private readonly List<PreloadClient> _activeClients = new List<PreloadClient>(); private void Preload(SlideHandler slide) { PreloadClient client = new PreloadClient(); _activeClients.Add(client); client.PreloadCompleted += client_PreloadCompleted; client.Preload(slide); } private void client_PreloadCompleted(object sender, SlidePreloadCompletedEventArgs e) { PreloadClient client = sender as PreloadClient; // do stuff client.PreloadCompleted -= client_PreloadCompleted; client.Dispose(); _activeClients.Remove(client); }
在这种情况下,您必须在处置主类时处置所有客户端:
protected override Dispose(bool disposing) { foreach (PreloadClient client in _activeClients) { client.PreloadCompleted -= client_PreloadCompleted; client.Dispose(); } _activeClients.Clear(); base.Dispose(disposing); }
注意这个实现不是线程安全的
- 访问
_activeClients
列表必须为made thread-safe ,因为您的PreloadCompleted
方法是从不同的线程调用的 - 您的包含对象可能会在客户端触发事件之前被释放。在那种情况下,“做事”应该什么都不做,所以这是您应该注意的另一件事。
- 在事件处理程序中使用
try
/finally
block 可能是个好主意,以确保在所有情况下都处理该对象
- 访问
关于c# - 如何处理调用了异步方法的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/974945/