Ars*_*ray 23 .net c# multithreading async-await
我正在尝试熟悉c#的新await/async关键字,我发现了几个我无法理解的方面.
让我们从竞争条件开始:
Stream s=...
...
for(int i=0;i<100;i++)
{
s.WriteAsync(new byte[]{i},0,1);
}
Run Code Online (Sandbox Code Playgroud)
这将按预期一直工作(例如写入文件12345 .....而不是13254或其他东西)?
第二件事是异步函数如果不包含await运算符则同步执行.而且,根据microsoft文档,异步函数总是在调用者线程中执行(与BeginInvoke相比).这带来了3个下一个问题:
异步函数在释放给调用函数之前执行了多少?
async void MyAsyncFunction()
{
Operation1();
Operation2();
Operation3();
....
Stream s=...;
await s.WriteAsync(....);
}
Run Code Online (Sandbox Code Playgroud)
在我读过的有关await/async的文章中,有人说没有等待操作符的异步函数按顺序执行,并且async/await立即返回.但它唠叨着我MyAsyncFunction
可能总是执行Operation1 ... Operation3,然后才会发布它await s.WriteAsync
.
如果我Thread.Sleep
在async函数中使用如下所示:
async void DoStuff()
{
Stream s=...;
...
await s.WriteAsync(....);
Thread.Sleep(10000);
....
}
Run Code Online (Sandbox Code Playgroud)
Thread.Sleep会阻塞执行它的整个线程还是只阻止异步函数?
如果我semaphore.Wait()
在其中一个异步函数中使用它会期望信号量被其他异步函数释放,该怎么办?这会像线程一样运行,还是会导致死锁?
await
在异步函数之外不起作用.为什么?
Ste*_*ary 16
我建议你阅读我的async
介绍.
这将按预期一直工作(例如写入文件12345 .....而不是13254或其他东西)?
不,你需要await
拨打电话WriteAsync
.
异步函数在释放给调用函数之前执行了多少?
直到它await
的操作尚未完成.
Thread.Sleep会阻塞执行它的整个线程还是只阻止异步函数?
Thread.Sleep
- 以及所有其他阻塞方法 - 将阻止async
方法和执行它的线程.
作为一般规则,请勿在方法中使用任何阻止方法async
.
如果我在其中一个异步函数中使用semaphore.Wait()并且它将期望由另一个异步函数释放信号量,该怎么办?这会像线程一样运行,还是会导致死锁?
这完全取决于你的背景.Wait
是一种阻塞方法,因此如果"其他" async
方法需要被阻塞方法保存的上下文,那么您将死锁.
请注意,这SemaphoreSlim
是async
友好的; 你可以用WaitAsync
而不是Wait
.
await在异步函数之外不起作用.为什么?
因为async
关键字启用了await
关键字.这样做是为了最大限度地减少新关键字对C#语言和代码可读性的影响.
Adr*_*ura 15
您可以await
在Eric Lippert的以下文章中找到有关操作员问题的答案,他说:
"await"运算符......并不意味着"此方法现在会阻止当前线程,直到异步操作返回".这将使异步操作回到同步操作,这正是我们试图避免的.相反,它意味着与此相反; 它意味着"如果我们正在等待的任务尚未完成,那么将该方法的其余部分作为该任务的继续进行注册,然后立即返回给您的呼叫者; 任务将在完成时调用continuation. - Eric Lippert
归档时间: |
|
查看次数: |
20741 次 |
最近记录: |