Marshalling exception with code from the ShareTarget second window

156 Views Asked by At

I'm having a hard time with some code I have that apparently struggles when called from the second window created by the ShareTarget contract (when you share something to the app, it opens in a small standalone window).

This is my code so far:

// Blur and resize the image to get the average HSL color
// Assume that stream is an IRandomAccessStream pointing to valid image data
HslColor hslMean;
using (RandomAccessStreamImageSource imageProvider = new RandomAccessStreamImageSource(stream))
using (BlurEffect blurEffect = new BlurEffect(imageProvider) { KernelSize = 256 })
{
    Color mean = await DispatcherHelper.GetFromUIThreadAsync(async () =>
    {
        WriteableBitmap
            blurred = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight),
            result = await blurEffect.GetBitmapAsync(blurred, OutputOption.Stretch),
            resized = result.Resize(1, 1, WriteableBitmapExtensions.Interpolation.Bilinear);
        return resized.GetPixel(0, 0);
    });
    hslMean = mean.ToHsl();
}

Note: that DispatcherHelper.GetFromUIThreadAsync method just checks the thread access to the UI thread, and if needed it schedules the code to a CoreDispatcher object that was obtained with CoreApplication.MainView.CoreWindow.Dispatcher.

Problem: this code works 100% fine if my app is already open, as at that point that CoreDispatcher object has already been created by previous calls to that DispatcherHelper class, so the method just uses the stored dispatcher to schedule the work and it works fine. But, if the app is closed when the ShareTarget window is opened (so that DispatcherHelper has to create the dispatcher for the first time) the CoreApplication.MainView.CoreWindow line throws an exception. A very weird one:

COMException: A COM call to an ASTA was blocked because the call chain originated in or passed through another ASTA. This call pattern is deadlock-prone and disallowed by apartment call control. A COM call (IID: {638BB2DB-451D-4661-B099-414F34FFB9F1}, method index: 6) to an ASTA (thread 10276) was blocked because the call chain originated in or passed through another ASTA (thread 4112). This call pattern is deadlock-prone and disallowed by apartment call control.


So, I needed a way to make that method reliable even when being called from different windows. I've tried different options:

#1: Just invoking that code without dispatching to a different thread, as in theory I should be on the UI thread at this point ---> FAIL (The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD)))

#2: Manually calling CoreApplication.MainView.CoreWindow.Dispatcher to dispatch that code block ---> FAIL (I get that weird COMException mentioned above)

#3: Manually using CoreApplication.MainView.Dispatcher to dispatch the code block (as it was the .CoreWindow part that spawned the exception) ---> FAIL (COMException: item not found)

#4: Using CoreApplication.GetCurrentView().CoreWindow.Dispatcher, CoreApplication.GetCurrentView().Dispatcher, Window.Current.CoreWindow.Dispatcher and Window.Current.Content.Dispatcher to schedule that code ---> FAIL (wrong thread again, I get the usual marshalling exception)

All these marshalling exception are thrown at the line result = await blurEffect.GetBitmapAsync(blurred, OutputOption.Stretch), so I suspect it might be something related to the Lumia Imaging SDK. I mean, I'm quite sure that I am in fact on the UI thread, or otherwise I wouldn't have managed to create an instance of the WriteableBitmap class, right?

Why is it that I can create WriteableBitmap objects (and they need to be created on the UI thread as far as I know), but that GetBitmapAsync method from the Lumia SDK always throws that marshalling exception? I'm using it everywhere in my app without any problems, why is it that it just won't work from the ShareTarget window? Is there anything I need to do?

Thanks for your help!

1

There are 1 best solutions below

1
On BEST ANSWER

Looks like this is a bug in the Lumia Imaging SDK (that was originally written for WP8.1, which didn't have multiple windows/dispatchers), so unless the call to the library is made from the dispatcher associated with the main app window (which of course can only be retrieved if the app is open in the background when the ShareTarget window pops up), it will just fail.

The only solution at this point is to replace that call to the Lumia SDK with some other code that doesn't rely on that particular library (in this case for example, it is possible to just get the ARGB array from the WriteableBitmap object and calculate the mean color manually).