c# - await/async 与线程有何不同?

标签 c# .net multithreading async-await

我正在尝试熟悉 c# 的新 await/async 关键字,但我发现有几个方面我不太理解。

  1. 让我们从竞争条件开始:

    Stream s=...
    ...
    for(int i=0;i<100;i++)
    {
        s.WriteAsync(new byte[]{i},0,1);
    }
    

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

    第二件事是异步函数如果不包含 await 运算符则同步执行。而且,根据微软文档,异步函数总是在调用者线程中执行(与 BeginInvoke 相比)。这让我想到接下来的 3 个问题:

  2. 异步函数在释放给调用函数之前执行了多少?

    async void MyAsyncFunction()
    {
        Operation1();
        Operation2();
        Operation3();
        ....
        Stream s=...;
        await s.WriteAsync(....);
    }
    

    在我读过的有关 await/async 的文章中,据说没有 await 运算符的异步函数按顺序执行,而带有 async/await 的则立即返回。但令我苦恼的是,MyAsyncFunction 可能总是在发布之前执行 Operation1...Operation3,因为它命中 await s.WriteAsync

  3. 如果我像这样在异步函数中使用 Thread.Sleep 会怎样:

    async void DoStuff()
    {
        Stream s=...;
        ...
        await s.WriteAsync(....);
        Thread.Sleep(10000);
        ....
    }
    

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

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

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

最佳答案

我建议您阅读我的 async intro .

will this work as expected all the time (e.g. write to the file 12345..... and not 13254 or something)?

没有。您需要等待 WriteAsync 的调用。

How much of an async function is executed before it releases to the caller function?

直到它等待一个尚未完成的操作。

Will Thread.Sleep block the whole thread in which it is executed or just the async function?

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

作为一般规则,不要在 async 方法中使用任何阻塞方法。

What if I use semaphore.Wait() in one of the async functions and it will expect for the semaphore to be released by an other async function. Will this behave as it would with threads, or will it cause deadlock?

这完全取决于您的上下文。 Wait 是一种阻塞方法,因此如果“其他”async 方法需要被阻塞方法持有的上下文,那么就会死锁。

请注意 SemaphoreSlim异步友好的;您可以使用 WaitAsync 而不是 Wait

await does not work outside of async functions. Why?

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

关于c# - await/async 与线程有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13429294/

相关文章:

c# - .NET 等同于将文件上传到 REST API 的 curl?

c# - Web 应用程序和 Web 表单之间的混淆

java - GLFW 的线程设置

c# - 如何强制重绘我的应用程序在任务栏中的条目?

c# - 在 C# 中嵌入资源

.net - LINQ to SQL : how to update the only field without retrieving whole entity

c++ - C++ 的双重检查锁是否有任何潜在问题?

c++ - 如何在单个 POSIX 线程中结合两种不同的等待机制?

c# - 如何在.net core中使用 "System.Net.ServicePointManager"?

c# - Web Api 模型绑定(bind)和多态继承