我正试图掌握Tasks和Async Await关键字。我有一个基本上调用 n 方法的示例方法。需要注意的两个要点是
这是代码。
public async void Handle<T>(T entry) {
await Task.Run(() => {
Parallel.ForEach(_handlers, pair => {
pair.Value.Invoke(_reference, new object[] {
entry
});
});
});
我的问题是我实际上从上面的代码中获得了任何异步或并行性吗?
答案 0 :(得分:5)
我假设您在UI应用程序中运行,因为服务器上的并行代码非常少见。
在这种情况下,在Task.Run
中包装并行代码是完全正常的,并且当您希望异步执行并行代码时,这是一种常见的模式。
我会做一些改变:
async void
。返回Task
,这样您就可以更干净地处理错误。Async
)结束您的方法。Task
而不是async
/ await
(如果您的整个async
方法只是await
任务,则可以避免一些开销只需直接返回任务。)像这样:
public Task HandleAsync<T>(T entry) {
return Task.Run(() => {
Parallel.ForEach(_handlers, pair => {
pair.Value.Invoke(_reference, new object[] {
entry
});
});
});
我还会考虑另外两种可能性:
Parallel.Invoke
代替Parallel.ForEach
。在我看来,Parallel.Invoke
与您实际尝试的内容更为匹配。public void Handle<T>(T entry)
),使用Task.Run
调用(例如await Task.Run(() => Handle(entry));
)。如果您的Handle[Async]
方法旨在成为通用库的一部分,那么您希望避免在异步方法中使用Task.Run
。答案 1 :(得分:1)
不,你在这里什么都没有。即使你让它返回Task
(以便调用者可以检查所有内容何时完成),如果没有异步,你会更好:
public Task Handle<T>(T entry)
{
return Task.Run(() =>
{
Parallel.ForEach(_handlers, pair =>
{
pair.Value.Invoke(_reference, new object[] { entry });
});
});
}