0

少し前に、次のコードに関する質問をMSDN フォーラムに投稿しました。新しいスレッドで作成し、ファイルからサムネイルを読み取り、Dispatcher を介して表示します。

private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        Task.Factory.StartNew(async()=>{
            var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder; ;

            var file = await localFolder.CreateFileAsync(".txt", Windows.Storage.CreationCollisionOption.OpenIfExists);
            var t = await file.GetThumbnailAsync(Windows.Storage.FileProperties.ThumbnailMode.DocumentsView);
            //Some proccessing....
            this.Dispatcher.Invoke(Windows.UI.Core.CoreDispatcherPriority.Normal,(a,b)=>{
                var bmp = new BitmapImage();
                bmp.SetSource(t); //Exception here
                image.Source = bmp;
            }, this, null);
            //Some more stuff...
        });
    }

imageは XAML の単なる Image コントロールです

上記のコードを実行すると、大きな例外が発生します。で例外が発生しbmp.SetSource(t)ます。

完全な例外情報は次のとおりです。

この RuntimeCallableWrapper の COM コンテキスト 0x1347668 への遷移が次のエラーで失敗しました: アプリケーションが入力同期呼び出しをディスパッチしているため、発信呼び出しを行うことができません。(HRESULT からの例外: 0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL))。これは通常、この RuntimeCallableWrapper が作成された COM コンテキスト 0x1347668 が切断されているか、他の処理でビジーでコンテキスト遷移を処理できないことが原因です。COM コンポーネントで要求を処理するためにプロキシは使用されず、COM コンポーネントへの呼び出しが直接行われます。これにより、破損やデータ損失が発生する可能性があります。この問題を回避するには、すべての COM コンテキスト/アパートメント/スレッドが有効なままであり、コンテキスト遷移に使用できることを確認してください。

Invoke の使用から InvokeAsync の使用に切り替えると問題は解決しますが、その理由が気になります。誰か説明できますか?

編集:上記は単なるテストコードです。私が作成したタスクは、非 UI スレッド コンテキストからファイルを読み取り、UI を更新する必要があるため、アプリで発生する非 UI スレッド コンテキストでの実行をシミュレートすることを目的としています。

4

1 に答える 1

2

TaskとにかくUIスレッドで呼び出すことになるだけなので、クリックハンドラーの内部の理由を理解できません。

private void Button_Click_1(object sender, RoutedEventArgs e)
{
  var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
  var file = await localFolder.CreateFileAsync(".txt", Windows.Storage.CreationCollisionOption.OpenIfExists);
  var t = await file.GetThumbnailAsync(Windows.Storage.FileProperties.ThumbnailMode.DocumentsView);
  var bmp = new BitmapImage();
  bmp.SetSource(t); //Exception here
  image.Source = bmp;
}
于 2012-04-20T00:48:38.303 に答える