Unhandled WinRT Exception: Platform::WrongThreadException

Dec 15, 2013 at 11:54 PM
The following unit test passes under Visual Studio 2013 - Windows 8, however fails under Visual Studio 2013 - Windows 8.1.

Any thoughts?
        TEST_METHOD(TestHelperFailsInVs2013)
        {
            TestHelper::RunUISynced([](){});
        }
Dec 16, 2013 at 5:54 PM
Hi Bill,

We're aware of the issue and are investigating a fix. We'll report back when we have more info.

Thanks for reporting!!
Dec 16, 2013 at 7:25 PM
Hi,

I was looking into this and I found that the error is thrown by dispatcher -> ProcessEvents(..) call, from TestHelper::TaskWait() method.
It seems that there is a known issue when calling ProcessEvents() in Windows 8.1 that crashes and throws this explicit error mentioned above:

CoreDispatcher.ProcessEvents method: "Calling this method recursively may cause your app to fail. Also, CoreDispatcher.ProcessEvents must be called only from the thread in which the CoreWindow was created. Calling this method from other threads will fail with an explicit error."

You may find more related information in the following MSDN documentation and forums:

I hope this helps,

Regards,
Gabriel Ostrowsky.
https://blogs.southworks.net/gostrowsky
Feb 19, 2014 at 5:07 PM
Here is an updated version of the AsyncHelper.h that makes them work correctly. there previous implementation was incorrect.

Note, this will work with most APIs but some APIs that use non agile objects won't work with this for those CoWaitForMultipleObjects() must be used.
//===============================================================================
// Part of this code is taken from http://hilo.codeplex.com
// License terms of Hilo project for this source code is located at
// http://hilo.codeplex.com/license
// A copy of MICROSOFT PATTERNS & PRACTICES LICENSE is also checkedin
// in file HiloLicense.txt with source at http://asynccppunittestlib.codeplex.com/
//===============================================================================
#pragma once
#include <ppltasks.h>
#include <wrl\wrappers\corewrappers.h>

namespace AsyncHelper
{
    template<typename T>
    T RunSynced(concurrency::task<T>& t)
    {
        Microsoft::WRL::Wrappers::Event event(CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS));
        if (!event.IsValid()) throw std::bad_alloc();

        t.then([&event](concurrency::task<T>)
        {
            SetEvent(event.Get());
        }, concurrency::task_continuation_context::use_arbitrary());

        WaitForSingleObjectEx(event.Get(), INFINITE, TRUE);
        return t.get();
    }

    inline void RunSynced(concurrency::task<void>& t)
    {
        Microsoft::WRL::Wrappers::Event event(CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS));
        if (!event.IsValid()) throw std::bad_alloc();

        t.then([&event](concurrency::task<void>)
        {
            SetEvent(event.Get());
        }, concurrency::task_continuation_context::use_arbitrary());

        WaitForSingleObjectEx(event.Get(), INFINITE, TRUE);
        t.get();
    }

    template<typename T>
    T RunSynced(Windows::Foundation::IAsyncOperation<T>^ action)
    {
        return RunSynced(concurrency::task<T>(action));
    }

    template<typename T, typename P>
    T RunSynced(Windows::Foundation::IAsyncOperationWithProgress<T, P>^ action)
    {
        return RunSynced(concurrency::task<T>(action));
    }

    template<typename P>
    void RunSynced(Windows::Foundation::IAsyncActionWithProgress<P>^ action)
    {
        RunSynced(concurrency::task<void>(action));
    }

    inline void RunSynced(Windows::Foundation::IAsyncAction^ action)
    {
        RunSynced(concurrency::task<void>(action));
    }
}