如果用户点击某个按钮,我正在使用WebClient的DownloadStringAsync方法下载html页面。如果他们想在完成当前操作并开始新操作之前停止当前操作,我调用CancelAsync方法并将WebClient对象设置为null。在第二个按钮的事件处理程序中,我还重新初始化WebClient对象,最后尝试下载新内容。 WebClient对象是一个全局变量。我得到的错误是:
WebClient does not support concurrent I/O operations.
有没有办法强制WebClient取消其当前操作并启动一个新操作?
答案 0 :(得分:3)
这似乎是您尝试在第一次下载完成之前下载第二个文件 - 使用相同的WebClient实例。创建WebClient的新实例肯定应该解决这个问题。 CancelAsync()尝试取消正在进行的下载,但它可能仍在运行一段时间。下载完成/取消后,将引发DownloadStringCompleted事件处理程序,允许您使用相同的WebClient实例开始新的下载。
答案 1 :(得分:1)
您看到的错误听起来更像是尝试跨线程使用WebClient,这是不允许的。换句话说,必须在同一个线程上创建WebClient,最终将调用DownloadStringAsync。合理? 你需要重新考虑一下你的设计。如果您确实希望全局访问WebClient实例,则可以考虑使用ThreadLocalAttribute。
答案 2 :(得分:0)
您可以编写单个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 块中处理,最后您可以在最后阻止。您还可以检查最终阻止以确认用户是否有canceled
操作,如果yes
则调用新的异步请求else
不执行任何操作。
我希望这就是你要找的东西。