locked
Call to UI thread from another thread in C++ DLL fail. HResult =0x8001010e RRS feed

  • Question

  • We have a c++ DLL component. It creates a thread that receives messages and trigger events to the Javascript UI thread. When the event handler in Javascript is called, it always throw an COMException:

    hr = 0x8001010e

    s = 0x04b82c30 L"The application called an interface that was marshalled for a different thread.\r\n"

    Since C++ DLL is allowed in WINRT, it is kind of confusing why it is not allowed to make calls to the UI thread from another thread. There seems lack of a mechanism for interacting with UI thread in WINRT. Thanks.

    Tuesday, March 13, 2012 7:18 PM

Answers

  • No, as I said and as is demonstrated in the sample I linked to it is possible to create and use threads in a C++ DLL component called from JavaScript.

    How does your JavaScript app initialize the C++ component? If it calls into it from the UI thread then the C++ component can cache the Dispatcher in that call (as the sample code does). If it doesn't already, then you can add an initialization function to do so.

    --Rob

    • Marked as answer by Renjie Huang Monday, March 19, 2012 7:15 PM
    Thursday, March 15, 2012 12:36 AM
    Moderator

All replies

  • You can switch to the UI thread with CoreDispatcher::InvokeAsync.

    This is demonstrated in Walkthrough: Creating a basic Windows Runtime component in C++ and calling it from JavaScript.

    --Rob

    Tuesday, March 13, 2012 7:36 PM
    Moderator
  • Hi Rob,

    Thanks for the prompt reply.

    I tried using CoreDispatcher::InvokeAsync as suggested. But it does not work for me. The problem is that GetForCurrentThread() returns nullptr:

    In my C++ thread (not the UI thread), I have the following code, and window is always nullptr after calling GetForCurrentThread().

    =============== Snipet of code =================

                Windows::UI::Core::CoreDispatcher ^ dispatcher = nullptr;
                Windows::UI::Core::CoreWindow ^ window = Windows::UI::Core::CoreWindow::GetForCurrentThread();
                if (nullptr != window) {
                    dispatcher = window->Dispatcher;
                }
                if (nullptr != dispatcher) {
                    dispatcher->InvokeAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
                                            ref new Windows::UI::Core::InvokedHandler([&] (Platform::Object ^ sender, Windows::UI::Core::InvokedHandlerArgs ^ e) {
                                                                                          _eventsAndProperties->FoundAdvertisedName(strName, (TransportMaskType)(int)transport, strNamePrefix);
                                                                                      }), nullptr, nullptr);
                }

    Tuesday, March 13, 2012 9:15 PM
  • Hi Renjie,

    You need to call into your component from the UI thread in JavaScript and then get the Dispatcher for that thread rather than spawning a new thread and trying to get the (non-existent) Dispatcher for that thread.

    If you look at the sample code I linked you'll see that it does just this. The first thing GetPrimesUnordered does is to save the Dispatcher off in a member variable. After that it kicks off the async call to do the actual calculation.

    --Rob

    Tuesday, March 13, 2012 9:33 PM
    Moderator
  • Hi Rob,

    Our use case is different from that. Our C++ thread in the DLL component receives TCP stream data and generate events to UI thread. Those actions are not initiated by the UI thread.

    According to your reply, it seems that it is not allowed to create/use thread in C++ DLL component in javascript. Is that true? I do not see documentation about this. Is there any solution for this (a different thread in DLL calls UI thread)?

    Tuesday, March 13, 2012 9:46 PM
  • No, as I said and as is demonstrated in the sample I linked to it is possible to create and use threads in a C++ DLL component called from JavaScript.

    How does your JavaScript app initialize the C++ component? If it calls into it from the UI thread then the C++ component can cache the Dispatcher in that call (as the sample code does). If it doesn't already, then you can add an initialization function to do so.

    --Rob

    • Marked as answer by Renjie Huang Monday, March 19, 2012 7:15 PM
    Thursday, March 15, 2012 12:36 AM
    Moderator
  • Hi Rob,

    Thanks for the information. It works for me.

    Monday, March 19, 2012 7:15 PM
  • Hi Rob,

    There is a question about the case with multiple arguments. In the example (http://msdn.microsoft.com/en-us/library/windows/apps/hh755833(v=vs.110).aspx)

    var handler_unordered = function (n)
    {
        document.getElementById('Primes').innerHTML += n.target.toString() + " ";
    };

    The event handler has only one argument and it is retrieved using "n.target.toString()". I am wondering how about the case when there are multiple arguments.

    In my app, the event handler has 3 arguments.

       this.BusListenerFoundAdvertisedName = function (sender, transport, name)

    From the debugging, it seems that the first one can be retrieved using "sender.target 2nd and 3rd arguments appears in sender.detail. It looks a bit puzzling to me.

    Monday, March 19, 2012 11:50 PM