lock中是不允许使用await方法的,在语法上通不过的。
但是如果需要在lock中调用async方法怎么办?需要同步调用async方法
如果不需要返回值,可以用wait()方法 如果需要返回值可以用Result。
例如 有个方法:
public async int Add(int a,int b)
{
await Task.Delay(1000);
return a+b;
}
一、如果在lock中使用的话,先说正确的
var re = Task.Run(()=>Add(1,2)).Result;
或
Task.Run(()=>Add(1,2)).wait();
解释一下:
- wait或result会堵塞当前线程,
- 然后从线程池里找个闲着的线程,执行Add方法
- 等待Add执行完毕后(或返回了结果),在解开原线程的堵塞
这样原线程就会接着往下走。
二、 错误的
能不能直接用Add(1,2).Result?
不可以的,我认为当方法中有await的时候,直接调用Result(wait)会导致死锁:
程序进入Add方法,当遇到await之前是以同步方法执行的,遇到了await后,会堵塞当前线程,等待await线程结束。
然后await去执行,当await执行完毕后(线程还没有结束),要返回给主线程,却发现主线程在堵塞,
然后导致子线程等待主线程,将结果返回回去;主线程等待子线程结束,好往下进行。
然后就差生了死锁。
三、 那为啥Task.Run(()=>Add(1,2)).Result就可以呢
详细解释一下
Result堵塞了当前主线程
然后执行了Task。Run方法,这个方法从线程池里又找了一个线程,叫子线程,然后子线程运行
然后子线程里面执行了Add方法,当执行到await时,子线程没有被堵塞(被堵塞的是主线程)
然后await 孙线程 去执行,执行完了后,返回给子线程
然后子线程结束,有了返回值
然后主线程解开堵塞