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 回答