2

我正在尝试掌握 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
            });
        });
    });

我的问题是我真的从上面的代码中获得了任何异步或并行性吗?

4

2 回答 2

5

我假设您在 UI 应用程序中运行,因为服务器上的并行代码非常罕见。

在这种情况下,将并行代码包装在 aTask.Run中是完全正常的,并且是您希望异步执行并行代码时的常见模式。

我会做一些改变:

  1. 避免async void。返回 a Task,这样您就可以更干净地处理错误。
  2. 遵循基于任务的异步模式命名约定(即,以 结束您的方法Async)。
  3. 直接返回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
            });
        });
    });

我还会考虑其他两种可能性:

  1. 考虑使用Parallel.Invoke而不是Parallel.ForEach. 在我看来,这Parallel.Invoke与您实际尝试做的事情更接近。(见下面 svick 的评论)。
  2. 考虑将并行代码留在同步方法中(例如,public void Handle<T>(T entry))并使用(例如, )调用它。如果您的方法旨在成为通用库的一部分,那么您希望避免在异步方法中使用。Task.Runawait Task.Run(() => Handle(entry));Handle[Async]Task.Run
于 2013-07-30T16:01:19.847 回答
1

不,你在这里一无所获。即使你让它返回Task(以便调用者可以检查一切何时完成)你最好不要异步:

public Task Handle<T>(T entry)
{
    return Task.Run(() =>
    {
        Parallel.ForEach(_handlers, pair => 
        {
            pair.Value.Invoke(_reference, new object[] { entry });
        });
    });
}
于 2013-07-30T15:27:15.607 回答