Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 一次下载多个URL(不阻塞用户界面,带有进度报告)_C#_Multithreading - Fatal编程技术网

C# 一次下载多个URL(不阻塞用户界面,带有进度报告)

C# 一次下载多个URL(不阻塞用户界面,带有进度报告),c#,multithreading,C#,Multithreading,我有一个Winform应用程序,它启动大约1000个web请求并处理结果。我现在正在使用BackgroundWorker,它在URL列表上循环,使用HTTPClient一个接一个地请求它们,处理结果,并使用BackgroundWorker.ReportProgress向用户界面报告进度 这很好,但我想通过一次请求多个URL来加快速度。它仍然应该报告进度,并且不能阻塞用户界面。我可以创建线程并自己完成所有工作,但我确信有一个更好的解决方案具有迷人的.NET功能。非常感谢您的帮助。是的,请使用Mic

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


这很好,但我想通过一次请求多个URL来加快速度。它仍然应该报告进度,并且不能阻塞用户界面。我可以创建线程并自己完成所有工作,但我确信有一个更好的解决方案具有迷人的.NET功能。非常感谢您的帮助。

是的,请使用Microsoft的反应式框架。它正是为这种事情而设计的

试试这个:

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()
,以便在UI线程上处理结果


对于基本位,只需获取“System.Reactive”,对于WinForms位,获取“System.Reactive.Windows.Forms”,对于WPF位,获取“System.Reactive.Windows.Threading”。

是的,使用Microsoft的Reactive框架。它正是为这种事情而设计的

试试这个:

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()
,以便在UI线程上处理结果


基本位只需NuGet“System.Reactive”,WinForms位只需“System.Reactive.Windows.Forms”,WPF位只需“System.Reactive.Windows.Threading”。

您只需执行Parallel.ForEach,它在每次循环后增加一个原子整数并更新UI。您只需执行Parallel.ForEach,在每个循环后增加一个原子整数,并更新UI。