异步编程基础
异步编程基础
死锁
ConfigureAwait
的作用?试图继续回夺取的原始上下文,则为
true
;否则为false
。什么情况下会造成死锁?
同步方法中调用异步方法,异步方法或异步方法中的异步方法(指
Task
),没有使用.ConfigureAwait(false)
。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21[Route("")]
[HttpGet]
public string Index()
{
System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId1:" + Thread.CurrentThread.ManagedThreadId);
var result = Test3().Result;
System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId4:" + Thread.CurrentThread.ManagedThreadId);
return result;
}
public static async Task<string> Test3()
{
System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId2:" + Thread.CurrentThread.ManagedThreadId);
using (var client = new HttpClient())
{
var response = await client.GetAsync(url);
System.Diagnostics.Debug.WriteLine("Thread.CurrentThread.ManagedThreadId3:" + Thread.CurrentThread.ManagedThreadId);
return await response.Content.ReadAsStringAsync();
}
}输出结果:
1
2
3> Thread.CurrentThread.ManagedThreadId1:5
> Thread.CurrentThread.ManagedThreadId2:5
>Test3().Result会阻塞主线程,等待Test3()中的线程执行完毕,会到主线程。Test3()中
await client.GetAsync(url)
, 会尝试获取当前线程上下文,这个上下文正在被主线程占用,并未释放,至此互相等待引起死锁。更正为await client.GetAsync(url).ConfigureAwait(false)
,会从线程池获取线程上下文,可避免这种情况。.ConfigureAwait(false),从线程池里获取新的线程,取消对SynchronizationContext的竞争。 .ConfigureAwait(true),与主线程竞争SynchronizationContext
特别注意:.net core 取消了SynchronizationContext,不再有死锁