我是否真的在这里使用任务和异步获得任何东西

McD*_*ean 2 c# task-parallel-library async-await

我试图掌握Tasks和Async Await关键字.我有基本上调用小样本方法Ñ的方法数.需要注意的两个要点是

  • 我不关心方法运行的顺序
  • 应该在后台线程上调用所有方法

这就是代码.

public async void Handle<T>(T entry) {
    await Task.Run(() => {
        Parallel.ForEach(_handlers, pair => {
            pair.Value.Invoke(_reference, new object[] {
                entry
            });
        });
    });
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*ary 5

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

在这种情况下,在a中包装并行代码Task.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
            });
        });
    });
Run Code Online (Sandbox Code Playgroud)

我还会考虑另外两种可能性:

  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