foreach执行异步下载无法正常工作

时间:2014-05-18 10:01:28

标签: c# asynchronous foreach download

我的应用程序从文本文件生成一个字符串数组,并在类中调用一个方法,填充字符串,调用它作为变量,如:

    void listafile()
    {
        WebClient client1 = new WebClient();
        client1.DownloadFile(new Uri("http://www.example.com/pack/content"), @".\pack\content");

        string[] lines = System.IO.File.ReadAllLines(@".\pack\content");

        foreach (string Pacchetto in lines)
        {
                startDownload(Pacchetto);

        }

startDownload(Pacchetto);是一个调用方法,在其中我使用带有异步下载的webclient对象来下载从数组中获取的每个文件。

所有看起来效果都好50%但是当Async下载开始时,Foreach循环产生很多下载并且在完成之前它们会自行杀死它们。

       void startDownload(string Pacchetto)
    {
        WebClient client = new WebClient();
        client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
        client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
        client.DownloadFileAsync(new Uri("http://www.example.com/pack/"+ Pacchetto), @".\pack\" + Pacchetto);
    }

你有没有想过如何对foreach周期说等待下载完成之后再启动另一个人而不用#34; client.DownloadFile"阻止所有程序。那不是异步?在这个课程中,有一个进度条和一个标签,显示下载的进度。

3 个答案:

答案 0 :(得分:0)

如果要按顺序下载文件,可以await DownloadFileAsync操作的结果。这不会阻止主线程,但仍然按顺序下载文件

async void startDownload(string Pacchetto)
{
    WebClient client = new WebClient();
    client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
    client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
    await client.DownloadFileAsync(new Uri("http://www.example.com/pack/"+ Pacchetto), @".\pack\" + Pacchetto);
}

答案 1 :(得分:0)

我会使用Microsoft的Reactive Framework(NuGet" Rx-Main")。

首先,我创建一个接受字符串(URL)的函数,并返回一个可观察的字符串:

Func<string, IObservable<string>> downloadStringObservable =
    u =>
        Observable.Using(
            () => new WebClient(),
            wc => Observable.Start(() => wc.DownloadString(u)));

现在我可以写一个非常简单的查询:

var query =
    from x in downloadStringObservable("http://www.example.com/pack/content")
    from y in x.Split(
        Environment.NewLine.ToCharArray(),
        StringSplitOptions.RemoveEmptyEntries).ToObservable()
    from z in downloadStringObservable(y)
    select new
    {
        url = y,
        data = z
    };

然后,我可以异步访问此查询的结果,如下所示:

query
    .Subscribe(x =>
    {
        /* do something with `x.url` & `x.data` */
    });

现在,如果你正在使用WinForms或WPF,你需要在UI线程上观察结果。这就像在Subscribe

之前添加这一个方法调用一样简单
query
    .ObserveOn(someExistingUIFormOrControl)
    .Subscribe(x =>
    {
        /* do something with `x.url` & `x.data` */
    });

易。 : - )

答案 2 :(得分:0)

你甚至可以在新线程中开始同步

new Thread(new ThreadStart(CompareVersions))。Start();