Concurrency::task.wait() throws invalid_operation

510 Views Asked by At

Concurrency::task.wait() throws invalid_operation exception: "Illegal to wait on a task in a Windows Runtime STA."

This exception occurs since ~14th November 2022 and seems to be Microsoft update related.

The exception does not occur, when building in Debug mode. Edit: it was true only for some Visual Studio versions. The latest release do throw the exception regardless of Debug or Release modes.

The code runs in a C++ application as managed-C++.

Any known Microsoft issues in this direction? Edit: the exception seems to be correct but it never showed up until some updates.

3

There are 3 best solutions below

0
Viktor Be On BEST ANSWER

The issue appears if single threaded COM initialization via CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); or CoInitialize(NULL); is done prior to calling Concurrency::task.wait().

The issue can be fixed by initializing COM with

CoInitializeEx(NULL, COINIT_MULTITHREADED);

or

Windows::Foundation::Initialize(RO_INIT_MULTITHREADED);

If you want to call Concurrency::task.wait() on a thread which is already initialized as COINIT_APARTMENTTHREADED and you cannot change it - start your concurrency task in a new thread via e.g. std::thread.

1
user2279376 On

I've also only recently encountered this error without any known changes to the code.

my issue involves the Microsoft C++ Rest SDK. specifically a call like

try {
        response = client.request(request).get();
} catch (...) {
}
0
user2279376 On

In my case at least, This was caused by an update to the 2022 VC++ redistributable.

https://github.com/microsoft/STL/pull/3255

It affects code the is compiled to the 2015 Visual Studio toolset, with machines that have the 2022 redist installed.

I was advised by the STL developer as follows:

I'd say the preference order is: Toolset upgrade > app-local DLLs > try to keep VS 2022 17.3's DLLs out of the machine. The last one is potentially a losing battle because any application being installed might try to install an updated VCRedist. Static linking would avoid it too, yes, but that would typically be an extremely invasive change for anything that's made out of multiple user DLLs.

Although presumably the issue has been identified and should be fixed in a future release of the VC++ redist.

As a temporary fix i was able to overcome the issue with code similar to : (Using the cpprestsdk)

try{
    auto task = client.request(request);
    while (!task.is_done()) { }
    response = task.get();
}