没有I/O的Async/Await

Owe*_*ove 1 c# asynchronous

我刚开始学习async/await.

有一篇Stephen Cleary的文章:https: //blog.stephencleary.com/2013/11/there-is-no-thread.html

我不太了解I/O但是...有人可以解释我如何为不使用I/O的操作应用async/await逻辑?

假设我们有一个string[]并且想要反转此数组中的所有字符串.

async Task<string> ReverseAsync(string s)
{
    char[] charArray = s.ToCharArray();
    Array.Reverse(charArray);
    return new string(charArray);
}
Run Code Online (Sandbox Code Playgroud)

然后我想"并行"为数组中的每个元素调用此方法.我知道像这样的代码不是有效的,但如何使用async/await实现呢?

Mic*_*kyD 5

有人可以解释我如何为不使用I/O的操作应用async/await逻辑?

您可以使用async/await.NET中的新功能来简化并发操作,而无需花费大量时间来解决可能昂贵的线程问题. async/await无论操作是CPU绑定还是IO绑定,都可以使用.

语法大致相同,只是对于CPU绑定操作,通常是明确调用Task.Run()或其版本. TasK可以被认为是一个高级构造来表示并发操作而不是同义词Thread. Task.Run将在最可能已经运行的线程池中的一个可重用线程中执行代码.操作完成后,将返回池中.

例如

await Task.Run (() => CalculatePrimeNumbersAsync (10000));
Run Code Online (Sandbox Code Playgroud)

在您的场景中,您应该尝试尽可能接近调用Task.Run()到callstack的顶部.这使你的代码:

  1. 更直观
  2. 显然被调用的操作是异步的
  3. 客户端代码可以完全控制根任务的创建
  4. 为客户端代码提供捕获当前上下文的机会(在GUI代码中特别有用)

然后我想"并行"为数组中的每个元素调用此方法.我知道像这样的代码不是有效的,但如何使用async/await实现呢?

您可能无法更改实现,但是您可以通过调用方法的方式来使用并发性.

所以给出你的代码:

async Task<string> ReverseAsync(string s)
{
    char[] charArray = s.ToCharArray();
    Array.Reverse(charArray);
    return new string(charArray);
}
Run Code Online (Sandbox Code Playgroud)

你会这样称呼它(让我们假设它是WinForms中的按钮单击处理程序):

async void OnButtonClicked (object sender, System.EventArgs e)
{
    var reversed = await Task.Run(() => ReverseString ("Miss Piggy is a Muppet"));
}
Run Code Online (Sandbox Code Playgroud)

请再次注意我们使用,Task.Run()因为客户端代码知道它ReverseString受CPU限制.如果要调用I/O绑定的内容(如WCF或Entity Framework),请不要使用Task.Run().

更多