2

我的场景:

  • 我有一个应用程序,人们可以在其中输入项目 ID 列表。
  • 对这些项目中的每一项运行 Web 服务上的操作
  • DataGridView 绑定到某些类的 BindingList/ObservableCollection,并在每个操作完成后更新
  • 还可能有一个状态标签,通知用户已经完成了多少项目。
  • 输入列表实际上可以是任何大小,但可能会限制在 500 左右。

我应该采用什么解决方案?线程池?根据需要创建/销毁线程?我编写了大部分代码,但需要搜索/更新不在 UI 线程上。从哪里开始是个好地方?

编辑:我必须使用 .NET 3.5 并且不能使用 async/await 之类的东西 :(

4

1 回答 1

3

一般来说,这听起来像是基于语言的async/await关键字可能是最好的选择,原因有两个:

  • 对这些项目中的每一项运行 Web 服务上的操作

鉴于这是一个 Web 服务调用,它自然是 IO 绑定和异步的。使用 TPL 或其他例程(不小心)可能会降低整体吞吐量。通常,您希望这些操作保持异步,并且如果您从一开始就以这种方式对待它们,则可以实现最佳扩展。

  • DataGridView 绑定到某些类的 BindingList/ObservableCollection,并在每个操作完成后更新
  • 还可能有一个状态标签,通知用户已经完成了多少项目。

鉴于您将 UI 控件绑定到结果,将调用映射回调用同步上下文的async/支持将简化将结果添加到集合中的过程。await这将使代码在其最终状态下保持非常简单。

请注意,您可能希望存储Task<T>异步操作返回的值,然后等待返回的值(而不仅仅是直接等待消息调用)。这将允许您同时触发对服务的多个请求。例如,您的代码可能看起来像(*没有异常处理等):

// Start each operation, and store in a list

var asyncOperations = ids.Select(id => FetchDataFromWebServiceAsync(id)).ToList();

while (asyncOperations.Any())
{
    // When one operation completes, remove it from the list of ops running
    var completed = await Task.WhenAny(asyncOperations);
    asyncOperations.Remove(completed);

    // Grab the result and use
    YourResultType finished = completed.Result;
    // Add to UI, update progress, etc...
}
于 2013-10-07T19:24:35.197 回答