1
public static void Init()
{
    //var task = GetSource1();
    //var task = GetSource2();
    //var task = GetSource3();
    var task = MyClient();
    MessageBox.Show(task.Result);
}

private static async Task<string> GetSource1()
{
    var sourceTask = WebClient();
    sourceTask.ConfigureAwait(false);
    return await sourceTask;
}

private static async Task<string> GetSource2()
{
    var sourceTask = MyClient();
    sourceTask.ConfigureAwait(true);
    return await sourceTask;
}

private static async Task<string> GetSource3()
{
    var sourceTask = MyClient();
    sourceTask.ConfigureAwait(false);
    return await sourceTask;
}

private static async Task<string> WebClient()
{
    return await new WebClient().DownloadStringTaskAsync("http://4pda.ru").ConfigureAwait(false);
}

private static Task<string> MyClient()
{
    var t = new Task<string>(() => new WebClient().DownloadString("http://4pda.ru"));
    t.ConfigureAwait(false);
    t.Start();
    return t;
}

这段代码工作正常。我得到了源代码MessageBox。但是,为什么我在使用时会出现死锁var task = GetSource3()?我认为它必须有效,因为我使用ConfigureAwait(false)并避免了上下文切换

4

1 回答 1

6

ConfigureAwait是一种纯粹的方法。它返回一个值,但对自身没有影响。它返回一个ConfiguredTaskAwaitable您需要等待的自定义可等待 ():

await task.ConfigureAwait();

但是,这不是您处理死锁的方式。这是一种预防措施,但您应该避免从一开始就阻塞异步代码。

于 2015-10-21T15:40:20.750 回答