0

SQLiteを利用するWindowsPhone8アプリがあります。

一部の非同期SQLite操作が無期限にハングするという問題があります(おそらくそれらが待機しているためですか?)

そのような操作の1つを次に示します。

SQLiteAsyncConnection conn = new SQLiteAsyncConnection("myDatabase");
var query = conn.Table<MyTable>().Where(x => x.Name == "name");
var result = await query.ToListAsync();

foreach (var item in result)
{
// breakpoint in the code here is never reached
}

これは、Task<文字列>を返す非同期メソッドにあります

このメソッドは、メインページのコードから早期に呼び出されます。アプリがこのメソッドにぶら下がっているため、メインページが実際にビルドされることはありません(停止するまで画面に「読み込み中...」と表示されます)

4

1 に答える 1

2

呼び出しスタックのさらに上(たとえば、メインページコード)で、を呼び出しResultていると思いますTask<T>。これにより、プログラムがデッドロックします。これについては、非同期プログラミングのベストプラクティスの記事と非同期コードでブロックしないブログ投稿で詳しく説明しています。

要約するとawait、未完了Taskの場合、デフォルトでは現在のコンテキストがキャプチャされasync、完了後にメソッドの残りの部分を復元するために使用されTaskます。あなたの場合、キャプチャされたコンテキストはUIコンテキストであり、指定されたスレッド(UIスレッド)でのみ実行されます。

したがって、メインページコードは、操作(UIコンテキストのキャプチャ)asyncであるメソッドを呼び出します。コードは、それを呼び出すメインページコードに未完了を返します。完了するまで(同期して)ブロックします。操作が完了すると、キャプチャされた(UI)コンテキスト内で残りのメソッドを実行しようとします。しかし、UIスレッドはビジーです。それが完了するのを待つのはブロックされています。したがって、デッドロック。awaitToListAsyncasyncTaskResultResultTaskToListAsyncasyncTask

于 2013-03-11T03:33:08.013 に答える