微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C# - 使用 ThreadPool 多次调用 Webclient.DownloadFileAsync

如何解决C# - 使用 ThreadPool 多次调用 Webclient.DownloadFileAsync

嗨,我是多线程的新手 - 我正在努力使用 DownloadFileAsync 从 Web 下载多个文件。大约有 400 个文件要下载,我准备了 URL 以使用 WebClient 类发送请求。我使用线程池调用了 DownloadfileAsync,希望它比串行下载更快。我使用的网址看起来像这样,每个网址的项目编号都会发生变化(104、105 等)。

http://medicarestatistics.humanservices.gov.au/statistics/do.jsp?_PROGRAM=%2Fstatistics%2Fmbs_item_standard_report&DRILL=ag&group=104&VAR=services&STAT=count&RPT_FMT=by+state&PTYPE=month&START_DT=202101&END_DT=202101

我的代码如下

            foreach(var d in infolist)
        {
            string itemtype = d.Key;
            Dictionary<string,string> folderAndurl = d.Value;
            foreach (var itemcode in itemcodes)
            {
                foreach (var date in dates)
                {
                        filename = folderAndurl["folder"] + date + "_" + itemcode + ".xls";
                        url = folderAndurl["url"].Replace("XXX",itemcode).Replace("STDATE",date);

                    ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(DownloadWebAsync),new object[] { filename,url });
                    //ThreadPool.QueueUserWorkItem(new WaitCallback(DownloadWebAsync),url });
                    

                }
            }
        }

下载WebAsync如下

    private void DownloadWebAsync(object state)
    {
        object[] list = state as object[];
        string filename = Convert.ToString(list[0]);
        string url = Convert.ToString(list[1]);

        WebClient client = new WebClient();
        Uri uri = new Uri(url);
        client.DownloadFileCompleted += new AsyncCompletedEventHandler(Client_DownloadFileCompleted);
        client.QueryString.Add("file",filename); 
        client.QueryString.Add("url",url); 
        client.DownloadFileAsync(uri,filename);


        //throw new NotImplementedException();
    }

当线程池启动时,我可以看到多个 BLANK 文件立即在磁盘上创建,如下图所示。 开始时它们的大小都是 0 KB 我假设 ThreadPool 中的所有线程都在运行并将请求发送到网站。

enter image description here

但是,在我看来,磁盘上的文件是使用从请求 1 一次或最多 2 个(一次最多 1 个)返回的下载数据进行更新的。 我的期望是对那些 0KB 文件同时进行更新-至少应该在某个时间点处理 3 或 4 个文件,因为调用 DownloadFileAsync 的线程已经在运行?我不知道我是否在代码或需要设置的任何属性方面做错了什么。我的期望是同时下载以缩短下载时间,但现在还没有发生。

我使用treadpool 的另一个原因是我将状态/url/下载大小写回UI 窗口,并且我不希望UI 在400 个文件下载期间没有响应。

我也在测试线程、线程池、任务并行库以及 Webclient、HttpClient(async/await) 等,但在所有情况下,似乎在线程或任务启动后,它会立即创建空白文件 -但实际下载发生在当时。还使用 WebClient.DownloadFile 进行了测试,并且通过线程池运行时会发生超时错误,因此我将不得不使用 Async。

有人可以帮我解释一下这是否是预期的行为,或者我该如何改善下载体验? 我已经为此苦苦挣扎了将近一周,非常感谢您的帮助。

问候

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。