2016-08-22 4 views
1

を返すために、ダイアログを待っている:何が起こるかC#メインスレッドが、私は次の方法持って

public override bool SyncNavigationMethod() 
{ 
    AsyncShowDialog().Wait(); 
    return true; 
} 

public Task AsyncShowDialog() 
{ 
    //code to show dialog and process user input from the dialog. 
} 

はSyncNavigationMethodが呼び出されたときにアプリがデッドロックに入るということです。

私はAsyncShowDialogが完了するのを待っているMainThread上で動作し、表示されているダイアログはそれを呼び出すMainThreadであるためコールバックを呼び出すことができないと思います。そして、メインスレッドはそれ自身を待っており、デッドロックです。

詳細情報:

  • ランタイム - UWP。
  • デバイス:電話(前述のように)デスクトップ(ダイアログが表示される前にアプリがフリーズします)。
  • 私はAsyncShowDialogで.Wait()\ .Resultを使用しようとしました。
  • AsyncShowDialogの実行中にコードが進行しないようにするためにAsyncShowDialogを呼び出した後、ManualResetEventを使用しようとしました。

デッドロックの疑いがありますか?

このデッドロックなしでSyncNavigationMethodからAsyncShowDialogを呼び出すにはどうすればよいですか?

ありがとうございました。

+0

、 'Task.WhenAll'または' Await'、 'Task.Wait/Task'のいずれかが必要です。WaitAll'はデッドロックを引き起こします –

答えて

2

私はUIを持たない非同期呼び出しの同期ブロッキングがデッドロックにつながる、それがコンソール以外のすべてのシステムのための本当の方法を、説明しステファン・クリアリー、で最高のブログpostの1、始まりますコンテキストスレッド:あなたのコードとの点については今

だから、メインスレッドは、それ自体に待機し、それがデッドロックです。

はい、それはあなたが正しくそれは、彼らのすべてが同期非同期コード、これと同じ結果

考えられる解決策をブロック自体は

Wait, Result and ManualResetEvent、ブロッキングによるMainthreadに、デッドロックだ理解している、い

Rest APIまたはweb based callの場合は、すべてAsyncとしてください。IISは、ポストトップレベルAsync-Awaitの実行sometを返すことができるようにします。以下のような興:Task<bool>

public async override Task<bool> SyncNavigationMethod() 
{ 
    await AsyncShowDialog(); 
    return true; 
} 

public async Task AsyncShowDialog() 
{ 
    await SomeOperation(); 
} 

戻り値は自動的に開封されただろう

その他のオプション:

あなたがSyncNavigationMethod() Asyncを作ることができない場合は、これを試してください:

UIスレッドの
public override bool SyncNavigationMethod() 
    { 
     List<Task> taskList = new List<Task>(); 
     taskList.Add(AsyncShowDialog()); 
     Task.WhenAll(taskList.ToArray()); 
     return true; 
    } 

    public async Task AsyncShowDialog() 
    { 
     await SomeOperation(); 
    } 
+1

'Task.WhenAll(....)は受け取ったすべてのタスクを待つタスクを返します。 それで、私もその作業を待つ必要があります。 これを行うと、私は 'AsyncShowDialog()'を別のタスクでラップしてしまい、役に立たないでしょう。 あなたの時間はまだあなたです。 私はあなたの最初の提案として、 'public async override Task SyncNavigationMethod()'をサポートするためにインフラストラクチャを変更しました。 –

+0

'ConfigureAwait(false).GetAwaiter().GetResult()'、しかし 'ConfigureAwait'を一番上の呼び出しまで使う必要があります。あなたはトップメソッド 'Async'を作る必要はありません –

関連する問題