【发布时间】:2018-10-08 17:07:05
【问题描述】:
我试图了解,当 WinForms 应用程序关闭时,WebClient 未完成的异步操作究竟会发生什么。我实际上没有问题,我的问题是出于了解确切流程的愿望。
应用程序在请求下载时使用以下模式:
using (WebClient wc = new WebClient())
{
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(my_DownloadProgressChanged);
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(my_DownloadFileCompleted);
事件处理程序是表单上的方法。我担心的一个问题是我不希望那些在表单已经关闭时被调用。我可以保留对 WebClient 的引用,并在表单关闭时 -=,但我不想做不必要的工作以避免出现新问题。
以下是我的问题:
- 为什么可以在异步操作完成之前 Dispose WebClient?
- 我们必须在主窗口关闭时取消注册处理程序吗? 如果我们不这样做会发生什么?我的观察是,如果我关闭表格,则没有 异步回调被调用,但究竟为什么,究竟是怎么做的 关机?
我查看了 WebClient 代码,但无法弄清楚这些内容。提前致谢。
【问题讨论】:
-
这个超级用户问题有你的答案superuser.com/questions/375604/…
-
长话短说,垃圾收集器和操作系统会尽最大努力在僵尸进程失控之前处理它们。在 C/C++ 之类的语言中,可以派生一个进程,并且它永远不会关闭,在主应用程序关闭后很长时间会消耗内存。这就是为什么在 C# 中使用“Dispose”模式是司空见惯的,例如“使用”并尝试/最终告诉 GC 和操作系统您已完成该对象并在需要时强制删除它。在像 C#/Java 这样的语言中,你只是一个经理,告诉保镖把你俱乐部里的某个人赶走。
-
下次开始异步下载时不应使用 using 语句。没有任何问题是 WebClient 从 Component 派生的副作用,这是他们无法再修复的 .NET 1.0 设计错误。您需要在 FormClosed 事件处理程序中调用其 CancelAsync() 方法以避免麻烦。
-
感谢@HansPassant,这是有道理的,这就是我的怀疑。但是,对于我的使用,我将采用我们在下面与 Eric 讨论的侵入性较小的更改。
标签: c# .net winforms webclient