WinRT中Dispatcher.invoke的线程问题

时间:2012-04-19 23:56:43

标签: c# multithreading windows-8 windows-runtime

前一段时间我在MSDN forum上发布了一个问题,涉及以下代码。它在新线程上创建,从文件中读取缩略图并通过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))。这是   通常因为COM上下文0x1347668所在   创建的RuntimeCallableWrapper已断开连接或正忙   做其他事情,不能处理上下文过渡。没有   代理将用于服务COM组件上的请求   将直接调用COM组件。这可能会导致   腐败或数据丢失。为避免此问题,请确保全部   COM上下文/公寓/线程保持活跃,可用   上下文转换,直到应用程序完全完成   RuntimeCallableWrappers,表示生活的COM组件   他们内心。

从使用Invoke切换到InvokeAsync修复了问题,但我想知道为什么。有人可以解释一下吗?

编辑:上面只是一些测试代码。我创建的任务是为了模拟在我的应用程序中出现的非UI线程上下文中的执行,因为它需要从非UI线程上下文中读取文件和更新UI。

1 个答案:

答案 0 :(得分: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;
}