我实际上在这里使用任务和异步获得了什么吗?
本文关键字:获得了 异步 什么 任务 实际上 在这里 | 更新日期: 2023-09-27 18:25:34
我正在尝试掌握任务和异步等待关键字。我有一个小示例方法,它基本上调用了 n 个方法。需要注意的两个关键点是
- 我不在乎方法的运行顺序
- 应在后台线程上调用所有方法
这是代码。
public async void Handle<T>(T entry) {
await Task.Run(() => {
Parallel.ForEach(_handlers, pair => {
pair.Value.Invoke(_reference, new object[] {
entry
});
});
});
我的问题是我实际上是否从上面的代码中获得了任何异步或并行性?
我假设您是在 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
});
});
});
我还会考虑另外两种可能性:
考虑使用(请参阅下面的svick评论(。Parallel.Invoke
而不是Parallel.ForEach
。在我看来,Parallel.Invoke
与你实际想要做的事情更接近。- 考虑将并行代码保留在同步方法中(例如,
public void Handle<T>(T entry)
(,并使用Task.Run
调用它(例如,await Task.Run(() => Handle(entry));
(。如果Handle[Async]
方法旨在成为通用库的一部分,则希望避免在异步方法中使用Task.Run
。
不,你在这里一无所获。即使您让它返回Task
(以便调用者可以在所有事情完成时进行检查(,您最好不要异步:
public Task Handle<T>(T entry)
{
return Task.Run(() =>
{
Parallel.ForEach(_handlers, pair =>
{
pair.Value.Invoke(_reference, new object[] { entry });
});
});
}