1

タイトル通り。ボタンをクリックすると、呼び出し行に配置されたブレークポイントでデバッガーに入ることができますopenPicker.PickSingleFileAsync()が、この呼び出しは返されません。ファイルを選択して[開く]をクリックすることはできますが、そのファイルで実際に何かを行うためにメソッドに戻ることはありません。これはすべて、ボタンと画像だけを備えた新しいWindowsMetroの「空白のアプリケーション」に含まれています。

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        OpenFile().Wait();
    }

    private async Task OpenFile()
    {
        FileOpenPicker openPicker = new FileOpenPicker();
        openPicker.ViewMode = PickerViewMode.Thumbnail;
        openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
        openPicker.FileTypeFilter.Add(".jpg");
        openPicker.FileTypeFilter.Add(".jpeg");
        openPicker.FileTypeFilter.Add(".png");

        // can break on following line
        var file = await openPicker.PickSingleFileAsync();

        // this line is never reached
        if (file != null)
        {
           // do stuff
        }
    }

これは、 MSDNのサンプルコードのとおりです。PickMultipleFilesAsyncを使用しても同じ結果が得られます。

明らかな何かが欠けていますか?

4

1 に答える 1

8

GUIアプリケーションを混在させないでくださいWait()awaitこれは、発生しているのとまったく同じように、デッドロックが非常に簡単に発生する可能性があるためです。

Wait()さらに言えば、使用できる場合は、おそらくまったく使用しないでください(ただし、例外があります。を使用するコンソールアプリケーションのメソッドでawait使用するのは理にかなっています)。Wait()Main()await

ここでの問題はWait()、UIスレッドをブロックすることです。ファイルピッカーが実行されると、残りのメソッドがUIスレッドで実行されるようにスケジュールされますが、この操作が完了するのを待機しているため、スレッドはそれを実行できません。したがって、この操作を完了するには、最初に完了する必要があります。これはデッドロックです。

ここでの解決策はawait、イベントハンドラーでも使用することです。

private async void Button_Click_1(object sender, RoutedEventArgs e)
{
    await OpenFile();
}
于 2012-05-10T11:28:45.820 に答える