WinRT 中 Dispatcher.invoke 的线程问题
本文关键字:线程 问题 invoke Dispatcher WinRT | 更新日期: 2023-09-27 18:31:48
我前段时间在MSDN论坛上发布了一个问题,涉及以下代码。它在新线程上创建,从文件中读取缩略图并通过调度程序显示它。
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...
});
}
图像只是 XAML 中的一个图像控件
如果执行上述代码,我会收到一个很大的异常。异常发生在 bmp.SetSource(t)
处。
以下是完整的异常信息:
转换为此运行时可调用包装器的 COM 上下文0x1347668失败,出现以下错误:无法进行传出呼叫,因为应用程序正在调度输入同步调用。(例外来自 HRESULT: 0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL))。这是通常是因为 COM 上下文0x1347668已创建的运行时可调用包装器已断开连接或繁忙执行其他操作,并且无法处理上下文转换。不代理将用于为 COM 组件上的请求提供服务,并且将直接调用 COM 组件。这可能会导致损坏或数据丢失。为避免此问题,请确保所有COM 上下文/单元/线程保持活动状态,可用于上下文转换,直到应用程序完全完成RuntimeCallableWrappers,表示存在的 COM 组件在他们里面。
从使用 Invoke 切换到 InvokeAsync 可以解决问题,但我想知道为什么。有人可以解释一下吗?
编辑:以上只是一些测试代码。我创建的任务旨在模拟在我的应用中发生的非 UI 线程上下文下的执行,因为它需要从非 UI 线程上下文读取文件和更新 UI。
我无法理解单击处理程序中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;
}