Foreach执行异步下载不能正常工作

本文关键字:工作 常工作 执行 异步 下载 不能 Foreach | 更新日期: 2023-09-27 18:03:48

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

    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对象与Async下载下载每个文件从数组。

所有似乎工作50%,但当异步下载开始时,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执行异步下载不能正常工作

我会使用微软的响应式框架(NuGet "Rx-Main")。

首先,我要创建一个函数,它接受一个字符串(URL)并返回一个string对象:

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

容易。: -)

如果您希望按顺序下载文件,您可以将DownloadFileAsync操作的结果await。这将不会阻塞主线程,但仍按顺序下载文件

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

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

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