首页 文章

线程的等待/异步有多么不同?

提问于
浏览
23

我正在尝试熟悉c#的新await / async关键字,我发现了几个我无法理解的方面 .

  • 让我们从竞争条件开始:
Stream s=...
...
for(int i=0;i<100;i++)
{
    s.WriteAsync(new byte[]{i},0,1);
}

这将按预期工作(例如写入文件12345 .....而不是13254或其他东西)?

第二件事是异步函数如果不包含await运算符则同步执行 . 而且,根据microsoft文档,异步函数总是在调用者线程中执行(与BeginInvoke相比) . 这带来了3个下一个问题:

  • 异步函数在释放给调用函数之前执行了多少?
async void MyAsyncFunction()
{
    Operation1();
    Operation2();
    Operation3();
    ....
    Stream s=...;
    await s.WriteAsync(....);
}

在关于await / async的文章中,我说've read, it' s表示没有等待操作符的异步函数按顺序执行,并且async / await立即返回 . 但它唠叨我 MyAsyncFunction 可能总是在释放之前执行Operation1 ... Operation3,因为它命中 await s.WriteAsync .

  • 如果我在异步函数中使用 Thread.Sleep ,如下所示:
async void DoStuff()
{
    Stream s=...;
    ...
    await s.WriteAsync(....);
    Thread.Sleep(10000);
    ....
}

Thread.Sleep会阻塞执行它的整个线程还是只阻止异步函数?

  • 如果我在其中一个异步函数中使用 semaphore.Wait() ,它会期望其他异步函数释放信号量,该怎么办?这会像线程一样运行,还是会导致死锁?

  • await 在异步函数之外不起作用 . 为什么?

3 回答

  • 15

    我建议你阅读我的async intro .

    这会一直按预期工作(例如写入文件12345 .....而不是13254或其他东西)?

    不 . 你需要 await 来调用 WriteAsync .

    在释放到调用函数之前,执行了多少异步函数?

    直到 await s尚未完成的操作 .

    Thread.Sleep会阻塞执行它的整个线程还是只阻止异步函数?

    Thread.Sleep - 以及所有其他阻塞方法 - 将阻止 async 方法和正在执行它的线程 .

    作为一般规则,请勿在 async 方法中使用任何阻止方法 .

    如果我在其中一个异步函数中使用semaphore.Wait(),它会期望信号量被其他异步函数释放 . 这会像线程一样运行,还是会导致死锁?

    这完全取决于你的背景 . Wait 是一种阻塞方法,因此如果"other" async 方法需要被阻塞方法保存的上下文,那么您将死锁 .

    请注意 SemaphoreSlimasync -friendly;你可以使用 WaitAsync 而不是 Wait .

    await在异步函数之外不起作用 . 为什么?

    因为 async 关键字启用 await 关键字 . 这样做是为了最大限度地减少新关键字对C#语言和代码可读性的影响 .

  • 0

    您可以在以下post by Eric Lippert中找到有关 await 运算符的问题的答案,其中他说:

    “await”运算符......并不意味着“此方法现在会阻止当前线程,直到异步操作返回” . 这将使异步操作回到同步操作,这正是我们试图避免的 . 相反,它意味着与此相反;它意味着“如果我们正在等待的任务尚未完成,那么将该方法的其余部分作为该任务的继续进行注册,然后立即返回给您的调用者;任务将在完成时调用continuation . - Eric Lippert

  • 16

    简而言之,似乎答案是“非常” . 虽然以下内容可能无法回答您的所有问题,但我认为它适用于一般情况下的用例 . 想想您的Stream而不是他们所指的网络IO .

    在重叠网络IO的情况下,将使用IO完成端口,回调由硬件中断触发 . 这意味着当我们“等待”完成时,不会消耗线程 . [...]可以在1个线程上执行所有操作 . [...]然而,它将依赖于平台,“awaiter”实现和正在使用的同步上下文 .

    http://social.msdn.microsoft.com/Forums/en-US/async/thread/a46c8a54-f8d4-4fa9-8746-64d6a3a7540d/

相关问题