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

3

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

WebClient does not support concurrent I/O operations. 

有没有一种方法可以强制WebClient取消当前操作并启动新操作?
3个回答

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

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

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()时,它可能会抛出一个异常,该异常在try-catch块中处理,最后您可以在finally块中调用一个新的异步请求。您还可以在finally块中放置检查以确认用户是否已经取消了操作,如果是,则调用新的异步请求else什么也不做。

我希望这就是您要寻找的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接