【发布时间】:2016-09-21 06:39:30
【问题描述】:
与我交谈的人提出了一段代码:
private void DownloadInformation(string id)
{
using (WebClient wc = new WebClient())
{
wc.DownloadStringCompleted +=
new DownloadStringCompletedEventHandler(DownloadStringCompleted);
wc.DownloadStringAsync(new Uri("http://www.fake.com/" + id));
}
}
以上是这个的简化版:
(我已获得作者的许可才能发布图片。)
该代码让我困扰的是附加了一个事件处理程序,DownloadStringAsync() 被调用,然后using 块结束,它在WebClient 上调用Dispose()。有什么可以防止WebClient 被using 处理掉,甚至在DownloadStringAsync() 完成和DownloadStringCompleted 事件触发之前收集垃圾?
有一个更新的方法,DownloadStringTaskAsync(),我认为可以与 await 结合使用:
private async Task DownloadInformation(string id)
{
using (WebClient wc = new WebClient())
{
wc.DownloadStringCompleted += DownloadStringCompleted;
await wc.DownloadStringTaskAsync(new Uri("http://www.fake.com/" + id));
}
}
然而,即便如此......我基本上会打赌事件触发器和处理程序会在 WebClient 被释放之前被调用。
我误解了WebClient 在这种情况下的生命周期还是这是一个糟糕的代码设计?
【问题讨论】:
-
您不需要
DownloadStringTaskAsync的事件。该任务应包含最终结果。换句话说:var content = await wc.DownloadStringTaskAsync(...);. -
@LasseV.Karlsen 好点——这肯定会解决这个问题。话虽如此,我肯定对第一个代码 sn-p 感到不安。
-
第一个例子被严重破坏了。不要使用它。让客户留在身边,直到活动完成。
-
请注意,最初链接帖子中的代码是正确的 - 否
using... -
第一个在stackoverflow.com/questions/979791/…(和rene 的回答)中讨论过,很尴尬,但很好。
标签: c# .net garbage-collection event-handling using-statement