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純粋な方法です。値を返しますが、それ自体には何の効果もありません。待機する必要があるカスタマイズされた awaitable ( ConfiguredTaskAwaitable) を返します。

await task.ConfigureAwait();

ただし、これはデッドロックを処理する方法ではありません。これは予防策ですが、そもそも非同期コードでのブロックは避けるべきです。

于 2015-10-21T15:40:20.750 に答える