我正在使用异步等待进行一些测试,因为我的一个单元测试根本没有返回,除非我要添加一个ConfigureAwait(false);参与其中一项任务。好吧,我决定找出那里到底发生了什么,并编写了以下测试。我不知道为什么,但匿名电话(3.)阻止,而1& 2不要。
我正在尝试检查与ilspy的差异,但我认为就这种行为得到一些意见会很有趣。我正在参加vs 2017 .net 4.5.2。我知道async void很糟糕......这不是重点。
[编辑]我添加了一些更多细节,因此您可以看到开头没有SyncContext,因为这是一个CONSOLE应用程序。此外,很久以前在这里发布了这类问题:https://blog.stephencleary.com/2012/02/async-console-programs.html
internal class Program
{
private static void Main(string[] args)
{
//System.Console.WriteLine($"Main dispatcher: {SynchronizationContext.Current?.GetHashCode()}");
//// 1. Method call - no blocking
//var mainTask = Task.Run(() => DoTheSame());
//mainTask.Wait();
// 2. Anonymous + Thread - no block
//var mainThread = new Thread(
//async () =>
//{
// System.Console.WriteLine($"Before setting dispatcher: {SynchronizationContext.Current?.GetHashCode()}");
// SynchronizationContext.SetSynchronizationContext(
// new DispatcherSynchronizationContext(
// Dispatcher.CurrentDispatcher));
// System.Console.WriteLine($"After setting dispatcher: {SynchronizationContext.Current?.GetHashCode()}");
// var ts = new TaskCompletionSource<bool>();
// await Task.Run(() =>
// {
// ts.SetResult(true);
// });
// await ts.Task;
//});
//mainThread.Start();
//mainThread.Join();
// 3. Anonymous + Task - blocks
var mainTask = Task.Run(
async () =>
{
System.Console.WriteLine($"Before setting dispatcher: {SynchronizationContext.Current?.GetHashCode()}"); // null of course
SynchronizationContext.SetSynchronizationContext(
new DispatcherSynchronizationContext(
Dispatcher.CurrentDispatcher));
System.Console.WriteLine($"After setting dispatcher: {SynchronizationContext.Current?.GetHashCode()}");
var ts = new TaskCompletionSource<bool>();
await Task.Run(() =>
{
ts.SetResult(true);
});
// using .ConfigureAwait(false); will make it work
await ts.Task;
});
mainTask.Wait();
}
private static async void DoTheSame()
{
System.Console.WriteLine($"Before setting dispatcher: {SynchronizationContext.Current?.GetHashCode()}");
SynchronizationContext.SetSynchronizationContext(
new DispatcherSynchronizationContext(
Dispatcher.CurrentDispatcher));
System.Console.WriteLine($"After setting dispatcher: {SynchronizationContext.Current?.GetHashCode()}");
var ts = new TaskCompletionSource<bool>();
await Task.Run(() =>
{
ts.SetResult(true);
});
await ts.Task;
}
}