带多个任务的WinForms TPL模式& UI同步-这是正确的吗? [英] WinForms TPL Pattern w/ Multiple Tasks & UI Sync - is this correct?
问题描述
我是TPL(任务并行库)的新手,我想知道以下方法是否是启动1个或多个任务,整理结果并将其显示在数据网格中的最有效方法.
I'm new to the TPL (Task-Parallel Library) and am wondering if the following is the most efficient way to spin up 1 or more tasks, collate the results, and display them in a datagrid.
- Search1& Search2与两个单独的数据库通信,但是返回相同的结果.
- 我禁用按钮并打开微调器.
- 我正在使用单个ContinueWhenAll方法调用来解雇任务.
- 我已将Scheduler添加到ContinueWhenAll调用中,以更新表单按钮,数据网格并关闭微调器.
问:我这样做正确吗?有更好的方法吗?
问:如何在此添加取消/异常检查?
问:如果需要添加进度报告,该怎么做?
Q: Am I doing this the right way ? Is there a better way ?
Q: How could I add cancellation/exception checking to this ?
Q: If I needed to add progress reporting - how would I do that ?
之所以选择此方法而不是说后台工作人员,是因为我可以并行执行每个DB任务,也可以按顺序触发每个DB任务.除此之外,我认为使用TPL可能会很有趣.但是,由于我在下面找不到我正在做的具体示例(多个任务),因此我认为将其放在此处可能会很不错.答案,并希望成为别人的榜样.
The reason that I chose this method over say, a background worker is so that I could fire each DB task off in parallel vs. sequentially. Besides that, I thought it might be fun to use the TPL.. however, since I could not find any concrete examples of what I'm doing below (multiple tasks) I thought it might be nice to put it on here to get the answers, and hopefully be an example for others.
谢谢!
代码:
// Disable buttons and start the spinner
btnSearch.Enabled = btnClear.Enabled = false;
searchSpinner.Active = searchSpinner.Visible = true;
// Setup scheduler
TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
// Start the tasks
Task.Factory.ContinueWhenAll(
// Define the search tasks that return List<ImageDocument>
new [] {
Task.Factory.StartNew<List<ImageDocument>>(Search1),
Task.Factory.StartNew<List<ImageDocument>>(Search2)
},
// Process the return results
(taskResults) => {
// Create a holding list
List<ImageDocument> documents = new List<ImageDocument>();
// Iterate through the results and add them to the holding list
foreach (var item in taskResults) {
documents.AddRange(item.Result);
}
// Assign the document list to the grid
grid.DataSource = documents;
// Re-enable the search buttons
btnSearch.Enabled = btnClear.Enabled = true;
// End the spinner
searchSpinner.Active = searchSpinner.Visible = false;
},
CancellationToken.None,
TaskContinuationOptions.None,
scheduler
);
推荐答案
问:我这样做正确吗?有更好的方法吗?
Q: Am I doing this the right way ? Is there a better way ?
是的,这是处理此类情况的好方法.就个人而言,我会考虑将UI的禁用/启用重构为单独的方法,但除此之外,这似乎非常合理.
Yes, this is a good way to handle this type of situation. Personally, I would consider refactoring the disable/enable of the UI into a separate method, but other than that, this seems very reasonable.
问:我该如何添加取消/例外检查?
Q: How could I add cancellation/exception checking to this ?
您可以将 CancellationToken 传递给您方法,并让他们检查并抛出请求取消的消息.
You could pass around a CancellationToken to your methods, and have them check it and throw if a cancellation was requested.
您将处理从taskResults获取结果的异常.这行:
You'd handle exceptions where you grab the results from taskResults. This line:
documents.AddRange(item.Result);
如果在操作过程中发生异常或取消操作,则该异常将在此处抛出(作为AggregateException
或OperationCanceledException
).
Is where the exception will get thrown (as an AggregateException
or OperationCanceledException
) if an exception or cancellation occurred during the operations.
问:如果我需要添加进度报告,我该怎么做?
Q: If I needed to add progress reporting - how would I do that ?
最简单的方法是将调度程序传递到您的方法中.完成此操作后,您可以使用它来计划在UI线程上更新的任务-即:Task.Factory.StartNew
并指定TaskScheduler
.
The simplest way would be to pass the scheduler into your methods. Once you've done that, you could use it to schedule a task that updates on the UI thread - ie: Task.Factory.StartNew
with the TaskScheduler
specified.
但是,由于我在下面找不到自己正在做的任何具体示例(多个任务)
however, since I could not find any concrete examples of what I'm doing below (multiple tasks)
仅供参考-我有系列的第18部分中的"nofollow>处理多个任务的示例 .
Just FYI - I have samples of working with multiple tasks in Part 18 of my series on TPL.
这篇关于带多个任务的WinForms TPL模式& UI同步-这是正确的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!