一次下载多个URL(不阻止用户界面,进度报告)

时间:2017-11-05 10:55:57

标签: c# multithreading

我有一个Winform应用程序,它启动大约1000个Web请求并处理结果。我现在正在使用BackgroundWorker,它循环遍历URL列表,使用HTTPClient一个接一个地请求它们,处理结果并将BackgroundWorker.ReportProgress的进度报告给用户界面。

这很好用,但我想通过一次请求多个网址来加快速度。它仍应报告进度,不得阻止用户界面。我可以创建线程并自己完成所有工作,但我非常确定有一个更好的解决方案,具有迷人的.NET功能。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:2)

是的,使用Microsoft的Reactive Framework。它专为这类事物而设计。

试试这个:

var urls = new []
{
    "http://www.microsoft.com",
    "http://www.google.com",
    "http://www.apple.com"
};

var query =
    from url in urls.ToObservable()
    from html in Observable.Using(
        () => new System.Net.Http.HttpClient(),
        client => Observable.FromAsync(() => client.GetStringAsync(url)))
    select new { url, html };

IDisposable subscription =
    query
        .ObserveOn(Scheduler.Default)
        .Subscribe(
            result =>
            {
                /* Process each `result.url` & `result.html`
                   as they come in */
            },
            exception => { /* handle exception */ },
            () => { /* All done successfully */ });

它都是多线程和异步的。创建的每个HttpClient都已正确处理,每个结果都会尽快显示。对于WinForms,.ObserveOn(Scheduler.Default)可以替换为.ObserveOn(formInstance),而对于WPF,.ObserveOnDispatcher()可以替换tf.nn.softmax_cross_entropy_with_logits,以便您在UI线程上处理结果。

Just NuGet" System.Reactive"对于基本位," System.Reactive.Windows.Forms"对于WinForms位,以及" System.Reactive.Windows.Threading"对于WPF位。