gpt4 book ai didi

c# - .NET:我是否需要在异步下载时保留对 WebClient 的引用?

转载 作者:可可西里 更新时间:2023-11-01 08:21:12 28 4
gpt4 key购买 nike

我在一段生产代码中使用了以下方法:

private void DownloadData(Uri uri)
{
WebClient webClient = new WebClient();
DownloadDataCompletedEventHandler eh = null;
eh = delegate(object sender, DownloadDataCompletedEventArgs e)
{
webClient.DownloadDataCompleted -= eh;
((IDisposable) webClient).Dispose();
OnDataDownloaded();
};
webClient.DownloadDataCompleted += eh;
webClient.DownloadDataAsync(uri);
}

我现在担心一个难以重现的错误可能是由于 WebClient 实例在调用 DownloadDataCompleted 事件之前被垃圾收集引起的:退出我的 之后DownloadData() 方法,没有对 WebClient 对象的明显引用,因此这可能会发生。

所以我的问题是:这真的会发生吗?我无法重现该问题,因此可能发生了一些内部事件,阻止了 WebClient 对象被垃圾收集(例如,该对象可能在等待响应时在某处注册了一个全局对象)。

代码在 .NET 2.0 上运行(如果有任何不同的话)。

最佳答案

不,在回调完成之前,您的对象不会被 GC-ed。根据Does the Garbage Collector destroy temporarily unreferenced objects during async calls in .NET? , "异步 API 保留对您的请求的引用(在异步 IO 操作所在的线程池中),因此在它完成之前不会被垃圾收集。"

但是,您的代码也在执行不需要的操作:您不需要分离事件处理程序,也不需要在网络客户端上调用 Dispose。 (Dispose() 实际上不是由 WebClient 实现的——您可以在 .NET Framework 引用源中看到这一点,网址为 http://referencesource.microsoft.com/netframework.aspx)。

因此您实际上不需要在回调中引用 webclient 实例。换句话说,下面的代码同样有效,并且避免了从委托(delegate)内部引用外部局部变量的任何潜在问题(上面讨论过)。

private void DownloadData(Uri uri)
{
WebClient webClient = new WebClient();
DownloadDataCompletedEventHandler eh = null;
eh = delegate(object sender, DownloadDataCompletedEventArgs e)
{
OnDataDownloaded();
};
webClient.DownloadDataCompleted += eh;
webClient.DownloadDataAsync(uri);
}

无论如何,您可能想在别处寻找错误的来源。我要查看的一个地方是 HTTP 调用的结果——您可能内存不足,可能遇到服务器错误等。您可以查看 e.Error 以查看调用是否实际工作。

关于c# - .NET:我是否需要在异步下载时保留对 WebClient 的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/979791/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com