我前段时间在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。