I’m just starting out with WinRT’s concurrency model. I have a task that I need to wait on, but calling wait() throws an exception that I can’t catch.
Simplest possible code:
concurrency::task<StorageFile^> getFileTask = concurrency::create_task(Windows::Storage::ApplicationData::Current->LocalFolder->GetFileAsync(fileString));
getFileTask.wait();
The exception it throws is:
Microsoft C++ exception: Concurrency::invalid_operation at memory location 0x0402C45C
How do I set this up so that it works?
One of the most important rules that you must follow when building a Windows Store app is that you must never block the UI thread. Never ever.
If you start an asynchronous operation, you get a
futureortaskthat “owns” that operation. If you callget()orwait()on that operation before the asynchronous operation has completed, that call will block until the operation completes, then it will return the result.Since blocking the UI thread is bad, if you attempt to synchronize with a not-yet-completed asynchronous operation on the UI thread, the call to
get()orwait()will throw, to prevent the UI thread from being blocked. This exception is there to help you to remember not to block the UI thread. 🙂You should use
task‘sthen()to provide a continuation that will run when the asynchronous operation completes. If the continuation needs to run on the UI thread as well, be sure to passtask_continuation_context::use_current()tothen()to ensure that the continuation is marshaled back to the UI thread for execution.Note: This exception is only thrown if you are using C++/CX. If you are using C++ without the C++/CX language extensions, the call to
get()orwait()will successfully block, potentially resulting in a poor user experience. In general, C++/CX has many more “guard rail” features like this one that are designed to make it easier for you to write good code. When using C++/CX, you get the full power of C++, with the understanding that there are more opportunities for error.