3

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

WebClient does not support concurrent I/O operations. 

有没有办法强制 WebClient 取消其当前操作并开始新的操作?

4

3 回答 3

3

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

于 2012-12-09T12:04:57.987 回答
1

您看到的错误听起来更像是在尝试跨线程使用 WebClient ,这是不允许的。换句话说,WebClient 必须在最终调用 DownloadStringAsync 的同一线程上创建。说得通?你需要重新考虑你的设计。如果您真的想保持 WebClient 的实例可全局访问,您可能会考虑使用 ThreadLocalAttribute。

于 2012-12-07T01:58:29.353 回答
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块中处理,最后你可以在finally块中调用一个新的异步请求。你也可以把 c​​heck in finally块来确认用户是否有canceled操作,如果yes然后调用新的异步请求else什么也不做。

我希望这就是你要找的。

于 2013-12-12T07:46:08.260 回答