Threading issue with Dispatcher.invoke in WinRT

0

I posted a question some time ago on MSDN forum involving the following code. It creates on a new thread, reads thumbnail from a file and displays it through 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 is just an Image control in the XAML

I get a big exception if above code executes. The exception occurs at bmp.SetSource(t).

Here is full exception info:

Transition into COM context 0x1347668 for this RuntimeCallableWrapper failed with the following error: An outgoing call cannot be made since the application is dispatching an input-synchronous call. (Exception from HRESULT: 0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL)). This is typically because the COM context 0x1347668 where this RuntimeCallableWrapper was created has been disconnected or it is busy doing something else and cannot process the context transition. No proxy will be used to service the request on the COM component and calls will be made to the COM component directly. This may cause corruption or data loss. To avoid this problem, please ensure that all COM contexts/apartments/threads stay alive and are available for context transition, until the application is completely done with the RuntimeCallableWrappers that represents COM components that live inside them.

Switching from using Invoke to InvokeAsync fixes the problem, but I'm wondering why. Can someone explain?

EDIT: Above is just some test code. The Task I created is meant to simulate execution under a non-UI thread context which occurs in my app since it need to both read files and update UI from a none-UI thread context.

c#
multithreading
windows-8
windows-runtime
asked on Stack Overflow Apr 19, 2012 by XiaoChuan Yu • edited Jun 20, 2020 by Community

1 Answer

2

I can't understand the reason for the Task inside the click handler given that you just end up invoking it on UI thread anyway.

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;
}
answered on Stack Overflow Apr 20, 2012 by Ritch Melton

User contributions licensed under CC BY-SA 3.0