在async/await C#中苦苦挣扎

coa*_*mee 9 .net c# asynchronous async-await

我读了很多async/await,但我仍然缺乏理解以下情况.

我的问题是,我应该像在DoSomething()或中那样实现我的"包装"方法DoSomethingAsync().

那么更好(以及为什么):我是否await在包装器方法中使用或直接返回Task?

        public static async void Main()
        {
            await DoSomething();
            await DoSomethingAsync();
        }

        private static Task DoSomething()
        {
            return MyLibrary.DoSomethingAsync();
        }

        private static async Task DoSomethingAsync()
        {
            await MyLibrary.DoSomethingAsync().ConfigureAwait(false);
        }

        public class MyLibrary
        {
            public static async Task DoSomethingAsync()
            {
                // Here is some I/O
            }
        }
Run Code Online (Sandbox Code Playgroud)

Ber*_*sch 8

Async/Await仍然相对较新,但有一些很好的做法可以帮助澄清API.基础是这样的:

  • 一种方法宣称自己async是预期await后来的意思
  • async隐含地Task为你创造了一个.
  • await就像一个书签.应用程序将恢复使用await关键字的位置.
  • 你不能做await任何事情IAwaitable(最常见的是Task)(引用)

在同时存在异步调用和同步调用的应用程序中,我们采用了命名约定:

  • async调用return TaskTask<T>将单词追加Async到名称的末尾.
  • 同步调用(默认)只是像任何方法一样工作,没有特殊的约定.

通常,可以有两种方法做同样的事情,但一种是同步的,另一种不是.你可以用两种不同的方式实现它,也可以用另一种方式包装一种方式.这实际上取决于您的需求以及将为您提供响应更快的应用程序.

在上面的示例中,处理异步和普通方法调用的正确方法是MyLibrary公开两个方法.这个例子是这样的:

 public static class MyLibrary
 {
     public static void DoSomething()
     {
         // do some work
     }

     public static async Task DoSomethingAsync()
     {
         // do similar work but use async API,
         // can also simply call DoSomething().
     }
 }

 // In another part of code would be called like this:
 public static async Task BiggerMethod()
 {
     MyLibrary.DoSomething();
     await MyLibrary.DoSomethingAsync();
 }
Run Code Online (Sandbox Code Playgroud)

您要避免的是async使用常规方法包装方法.只要您与工作Task直接,你失去的所有优势async,并await和你介绍的地方,你的代码可以死锁.


Ant*_*t P 4

Berin 的答案很好,但没有明确解决您问题中的具体情况,如下所示:

1:直接返回任务

private static Task DoSomething()
{
    return MyLibrary.DoSomethingAsync();
}
Run Code Online (Sandbox Code Playgroud)

2:等待任务并返回结果

private static async Task DoSomethingAsync()
{
    await MyLibrary.DoSomethingAsync().ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,直接返回Task和等待Task以及返回响应之间的唯一区别是 - 在后一种情况下 - 框架必须创建一个状态机来管理等待 的方法的启动、挂起和继续Task。这会产生一些性能开销。

一般来说,如果你可以返回 aTask并允许它在更高的位置等待,那么你应该这样做。然而,在大多数(但肯定不是全部)实际情况下,这是不可能的,因为您需要在返回之前对结果执行一些处理(这正是 async/await 帮助您实现的目标)。