代码之家  ›  专栏  ›  技术社区  ›  ca9163d9

`等待任务。运行(()=>dowork1async())`而不是'await dowork1async()'?

c#
  •  1
  • ca9163d9  · 技术社区  · 6 年前

    有以下几种方法,

    async Task DoWork1Async() { .... };
    async Task DoWork2Async() { .... };
    async Task DoWork3Async() { .... };
    

    我读了下面的代码

    await Task.Run(() => DoWork1Async());
    await Task.Run(() => DoWork2Async());
    await Task.Run(() => DoWork3Async());
    

    而不是

    await DoWork1Async();
    await DoWork2Async();
    await DoWork3Async();
    

    这两者有什么区别?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Brandon    6 年前
    await Task.Run(() => DoWork1Async());
    

    启动一个任务,它将调用 DoWork1Async . 不管怎样,这都保证是异步的 DOWORK1ASYNC 已实现。

    注释 : Task.Run(Action<Task<T>>) 返回A Task<T> , Task<Task<T>> . 当lambda返回任务时,task.run()返回一个任务,该任务在内部任务的结果下完成。所以你不必做像 await await Task.Run(() => return a Task) .


    await DoWork1Async();
    

    电话 DOWORK1ASYNC 在当前线程上同步。如果 DOWORK1ASYNC 执行一个 await 语句,则工作将挂起,其余工作将异步进行。然而,如果 小精灵 完成执行而不命中 等待 ,则控件将返回给调用方,然后将启动 DoWork2Async 都是同步的。


    所以简而言之,第一种形式保证了DoWork1Async不会同步启动或完成。

    第二个表单将同步启动dowork1async,甚至可能同步完成它,这取决于它是如何编写的。

    —— 这里有一把小提琴显示出不同:

    https://dotnetfiddle.net/GhrO8x

    注意在第一种情况下 DoWork() 在我们等待它之前完全同步地开始和执行 Task 而在第二种情况下,它在我们等待它的任务之后异步执行。

        2
  •  1
  •   Flydog57    6 年前

    当您运行(在标记为 async )

     await DoWork1Async();
    

    你的代码调用 DoWork1Async 编译器在状态机中设置。此时,代码将放弃控制权返回到状态机。任务完成后,方法中的其余代码将继续。

    记住这一点 异步的 代码不一定在单独的线程上运行(例如,如果您正在执行异步I/O)。

    当你跑步时:

     await Task.Run(() => DoWork1Async());
    

    你的 小精灵 作为工作分派到线程池。它在不同的线程(线程池线程)上执行。当这项工作完成时,相同的状态机机制将控制权交还给代码以继续运行。

    在第二种情况下,代码总是在线程池线程上运行。在第一种情况下,您可能根本没有使用额外的线程(取决于DoWork1Async的编码方式)