不能使用DownloadFileAsync下载多个文件

本文关键字:文件 下载 DownloadFileAsync 不能 | 更新日期: 2023-09-27 18:18:06

我正在为自己开发一个应用程序,实际上这个应用程序是用于下载我们公司使用的最新版本的防病毒软件
在这个应用程序中,我想使用DownloadFileAsync方法下载我的文件,但它不工作,我得到这个错误:

WebClient does not support concurrent I/O operations.

我的源代码:

private static WebClient wc = new WebClient();
        private static ManualResetEvent handle = new ManualResetEvent(true);
        private DateTime myDate = new DateTime();
        private void btn_test_Click(object sender, EventArgs e)
        {
            using (WebClient client = new WebClient())
            {
                client.Encoding = System.Text.Encoding.UTF8;
                var doc = new HtmlAgilityPack.HtmlDocument();
                ArrayList result = new ArrayList();
                doc.LoadHtml(client.DownloadString("https://www.symantec.com/security_response/definitions/download/detail.jsp?gid=savce"));
                foreach (var href in doc.DocumentNode.Descendants("a").Select(x => x.Attributes["href"]))
                {
                    if (href == null) continue;
                    string s = href.Value;
                    Match m = Regex.Match(s, @"http://definitions.symantec.com/defs/('d{8}-'d{3}-v5i(32|64)'.exe)");
                    if (m.Success)
                    {
                        Match date = Regex.Match(m.Value, @"('d{4})('d{2})('d{2})");
                        Match filename = Regex.Match(m.Value, @"'d{8}-'d{3}-v5i(32|64)'.exe");
                        int year = Int32.Parse(date.Groups[0].Value);
                        int month = Int32.Parse(date.Groups[1].Value);
                        int day = Int32.Parse(date.Groups[3].Value);
                        myDate = new DateTime(
                                Int32.Parse(date.Groups[1].Value),
                                Int32.Parse(date.Groups[2].Value),
                                Int32.Parse(date.Groups[3].Value));
                        listBox1.Items.Add(m.Value);
                        if (myDate == DateTime.Now)
                        {
                            Download(m.Value,filename.Value);
                        }
                        else
                        {
                            MessageBox.Show("There is no Update!");
                        }
                    }
                }
            }
        }
        private void Download(string url, string fileName)
        {
            wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
            wc.DownloadFileAsync(new Uri(url), @"''10.1.0.15'Symantec Update Weekly''" + fileName);
            //wc.DownloadFile(url, @"''10.1.0.15'Symantec Update Weekly''" + fileName);
        }
        private void WcOnDownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (!e.Cancelled && e.Error == null)
            {
                //async download completed successfully
            }
            handle.Set();
        }
        private void wc_DownloadProgressChanged(object sender, System.Net.DownloadProgressChangedEventArgs e)
        {
            double bytesIn = double.Parse(e.BytesReceived.ToString());
            double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
            double percentage = bytesIn / totalBytes * 100;
            progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString());
        } 

当我的应用程序试图下载文件时,
以上方法似乎无法同时下载多个文件。
我搜索了很多,找到了这个解决方案,但我不能把它应用到我的应用程序中。我怎样才能解决这个问题呢?
谢谢你的建议。

不能使用DownloadFileAsync下载多个文件

// Declare a field to hold the Task
private static Task DownloadTask;
private Task Download(string url, string fileName)
{
    var wc = new WebClient();
    wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
    return wc.DownloadFileTaskAsync(new Uri(url), @"''10.1.0.15'Symantec Update Weekly''" + fileName);
}

你可能需要修改进度条来处理多线程。

Inside btn_test_Click

// Before foreach
var tasks = new List<Task>();
// Inside foreach
if (myDate == DateTime.Now)
{
    MessageBox.Show("Updates are New");
}
else
{
    tasks.Add(Download(m.Value,filename.Value));
}
// After foreach
// You can also set the TimeSpan value and update the progressbar
// periodically until all the tasks are finished
DownloadTask = Task.WhenAll(tasks);

参见Task.WaitAll, WebClient.DownloadFileTaskAsync