少し前に、次のコードに関する質問を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 スレッド コンテキストでの実行をシミュレートすることを目的としています。