【问题标题】:What happens to outstanding .NET WebClient async operations when WinForm app closes?WinForm 应用程序关闭时未完成的 .NET WebClient 异步操作会发生什么?
【发布时间】: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


【解决方案1】:

为什么可以在异步操作完成之前 Dispose WebClient?

查看 WebClient 的 Reference Source,看起来它实际上没有针对 Dispose 方法的任何特定实现。 不应该处置任何 IDisposable 并期望异步操作成功完成,但在这种情况下它可能会发生,因为处置 Web 客户端不会做任何事情来中止打开的连接。

关于您关于应用程序退出时会发生什么的问题,操作系统将在进程结束时终止所有打开的连接。

【讨论】:

  • 嗯,WebClient.Dispose 对我来说似乎并不空。但是,关于第二个问题:Form关闭后是否可能会调用回调?
  • 表格关闭后:是的。申请关闭后:否
  • 由于这些回调是在 UI 线程上调用的,我假设添加一个检查以查看表单是否已经关闭并返回应该防止与 UI 控件发生不希望的交互,可能已经处理?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
  • 2013-03-10
相关资源
最近更新 更多