Chr*_*old 4 c# design-patterns idisposable async-await
在使用一次性对象时,我遇到了尝试并行处理多个任务(或运行时感觉合适)的问题.在下面的代码片段中,每个Processor对象在完成所需工作之前立即处理.
async public Task ProcessData(IEnumerable<int> data)
{
var tasks = new List<Task>();
foreach (var d in data)
{
using (var processor = new Processor(d))
{
processor.Completed += (sender, e) => { // Do something else };
tasks.Add(processor.ProcessAsync());
}
}
await Task.WhenAll(tasks);
}
Run Code Online (Sandbox Code Playgroud)
重写代码如下导致每个处理器执行其处理并且然后处理,但这不是运行不依赖于彼此的多个任务的最有效方式.
async public Task ProcessData(IEnumerable<int> data)
{
foreach (var d in data)
{
using (var processor = new Processor(d))
{
processor.Completed += (sender, e) => { // Do something else };
await processor.ProcessAsync();
}
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么第一个例子处理'早期'并给出这种情况的最佳代码模式的例子.
它有助于await将当前方法视为暂停,即使它不会阻塞该线程.
在第一个示例中,当您执行foreach循环时,每次创建一个Processor,启动一个操作(将操作保存Task在列表中),然后处理Processor.你的后foreach循环结束,那么你(异步)等待所有操作完成.
在第二个示例中,当您执行foreach循环时,每次创建一个Processor,启动一个操作,(异步)等待它完成,然后处理Processor.
要解决这个问题,你应该编写一个帮助方法,如下:
private static async Task ProcessData(int data)
{
using (var processor = new Processor(d))
{
processor.Completed += (sender, e) => { /* Do something else */ };
await processor.ProcessAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
您的帮助程序方法定义了一个更高级别的操作,它将Processor在适当的时候处理自己的资源.然后您可以同时开始所有工作:
public async Task ProcessData(IEnumerable<int> data)
{
...
await Task.WhenAll(data.Select(d => ProcessData(d)));
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1414 次 |
| 最近记录: |