我正在尝试熟悉 c# 的新 await/async 关键字,但我发现有几个方面我不太理解。
让我们从竞争条件开始:
Stream s=... ... for(int i=0;i<100;i++) { s.WriteAsync(new byte[]{i},0,1); }
这会一直按预期工作吗(例如,写入文件 12345..... 而不是 13254 或其他东西)?
第二件事是异步函数如果不包含 await 运算符则同步执行。而且,根据微软文档,异步函数总是在调用者线程中执行(与 BeginInvoke 相比)。这让我想到接下来的 3 个问题:
异步函数在释放给调用函数之前执行了多少?
async void MyAsyncFunction() { Operation1(); Operation2(); Operation3(); .... Stream s=...; await s.WriteAsync(....); }
在我读过的有关 await/async 的文章中,据说没有 await 运算符的异步函数按顺序执行,而带有 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
在异步函数之外不起作用。为什么?
最佳答案
我建议您阅读我的 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/