1

使用 C# 4.0,我想知道一种从下面显示的函数 foo() 中更新 UI 的简单可靠的方法。我需要更新一些显示处理的 url 数量和找到的坏链接数量的文本框。我对异步任务采取的一般方法是基于我在这里找到的一种方法:

如何异步使用 HttpWebRequest (.NET)?

Pseudo Code in my code-behind on the form:

1. populate a ConcurrentBag
2. Task.Factory.StartNew ( () =>
          Parallel.ForEach( ConcurrentBag, (d) =>
           {
             MyAsyncTask(d);

           }

MyAsyncTask 会:

          <snip>
          try
            {

             IAsyncResult result = myWebRequest.BeginGetResponse (
               new AsyncCallback( foo, state);



            ThreadPool.RegisterWaitForSingleObject(
            result.AsyncWaitHandle,
            new WaitOrTimerCallback(TimeoutCallback),
            state,
            (MSEC * 1000),  
            true
            );

           }
          catch (Exception ex) {}

            private void foo(IAsyncResult result)

            {
            RequestState state = (RequestState)result.AsyncState;
            WebRequest request = state.webRequest;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);

            //update the UI ??

            }
4

2 回答 2

1

首先,进行一点代码审查:

  • 你不需要ConcurrentBag(a List<>will do)
  • 你不需要Parallel.ForEach(). BeginGetResponse()不阻塞
  • 出于同样的原因,您甚至可能不需要 Factory.StartNew() 任务
  • 仅使用catch (Exception ex) {}隐藏错误

应用它,您将拥有更简单的代码。

然后,foo(IAsyncResult result)您可以使用Control.Invoke(). 像这里一样,这已经被问过很多次了。

于 2013-07-24T20:32:30.487 回答
0

你说:

我的任务是编写迭代 100K URL 并测试每个 URL 是活动还是死的东西,并让该过程花费尽可能少的时间。

你不需要异步。只需这样做:

IEnumerable<string> urls = GetUrls(); //you provide this
var results =
 urls
 .AsParallel().WithDegreeOfParallelism(50)
 .Select(url => CheckUrl(url))
 .ToList();

PLINQ 为您处理所有并行和同步。只需提供一个同步CheckUrl功能。将可能的异常存储在任何CheckUrl返回中。

异步最适合 WinForms/WPF 或当您有大量线程时。50 不是“吨”。

于 2013-07-25T14:48:06.700 回答