WebClient不支持并发I / O操作。

如果用户点击某个按钮,我正在使用WebClient的DownloadStringAsync方法下载html页面。 如果他们想要在完成当前操作并开始新操作之前停止当前操作,我调用CancelAsync方法并将WebClient对象设置为null。 在第二个按钮的事件处理程序中,我还重新初始化WebClient对象,最后尝试下载新内容。 WebClient对象是一个全局变量。 我得到的错误是:

WebClient does not support concurrent I/O operations. 

有没有办法强制WebClient取消其当前操作并启动一个新操作?

这似乎是您尝试在第一次下载完成之前下载第二个文件 – 使用相同的WebClient实例。 创建WebClient的新实例肯定应该解决这个问题。 CancelAsync()尝试取消正在进行的下载,但它可能仍在运行一段时间。 下载完成/取消后,将引发DownloadStringCompleted事件处理程序,允许您使用相同的WebClient实例开始新的下载。

您看到的错误听起来更像是尝试跨线程使用WebClient,这是不允许的。 换句话说,必须在同一个线程上创建WebClient,最终将调用DownloadStringAsync。 合理? 你需要重新考虑一下你的设计。 如果您确实希望全局访问WebClient实例,则可以考虑使用ThreadLocalAttribute。

您可以编写单个WebClient类,并且可以在具有不同异步请求的循环中调用它。 如,

  WebClient client = new WebClient(); try { client.DownloadStringCompleted += (object newSender, DownloadStringCompletedEventArgs e) => { Dispatcher.BeginInvoke(() => { try { var response = e.Result; // your response logic. } catch (Exception) { MessageBox.Show("Problem occured"); } }); }; } catch { MessageBox.Show("Problem occured"); } finally { if (userHasCanceled) client.DownloadStringAsync(new Uri("xyz")); } client.DownloadStringAsync(new Uri("abc")); 

所以当你调用client.CancelAsyn()它可能抛出一个exception ,它在try-catch块中处理,最后你可以在finally块中调用一个新的异步请求。 您还可以将check in finally块确认是否已canceled操作,如果yes则调用新的异步请求, else不执行任何操作。

我希望这就是你要找的东西。