无法使用DownloadFileAsync下载多个文件

时间:2013-06-12 12:59:52

标签: c# asynchronous

我正在为自己开发一个应用程序,实际上这个应用程序用于下载我们公司正在使用的最新版本的防病毒软件。 在此应用程序中,我想使用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());
        } 

当我的应用程序尝试下载文件时,
看来上面的方法不能同时下载多个文件 我经常搜索this solution,但我无法将其应用到我的应用程序中 我该怎么解决呢。
谢谢你的建议。

1 个答案:

答案 0 :(得分:3)

// 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);
}

您可能需要更改进度条以处理多个线程。

内部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.WaitAllWebClient.DownloadFileTaskAsync