locked
File I/O, Async API blocking on the UI thread

    Question

  • I need some help on how to properly handle IO in an RT app without blocking the UI thread.

    I have something like:

    create_task(FileIO::ReadBufferAsync(file)).then( [Load](task<IBuffer^> bufferTask) { try { IBuffer^ buffer = bufferTask.get(); DataReader^ reader = DataReader::FromBuffer(buffer); Load(reader); return; } catch (Platform::COMException ^e) { // ...
    } });

    Where Load is a lambda that I can pass in to load the data.

    The problem is that everything in the task's lambda seems to be executing on the UI thread.  I was assuming that the continuation of ReadBufferAsync would be on a separate thread, but this does not seem to be the case.

    What's happening here?  How is it that that Load(reader) is getting called on the UI thread, and what is the correct way to handle file IO off of the UI thread.  Should I just spawn & detach a "loading" thread before doing this, or am I missing something?

    Thanks!

    Friday, March 22, 2013 1:45 AM

Answers

  • The UI of a Windows Store app runs in a single-threaded apartment (STA). A task whose lambda returns either an IAsyncAction or IAsyncOperation will run in the STA, by default, if it is created from STA, unless you specify otherwise. If a task that doesn't return an IAsyncAction or IAsyncOperation, is not apartment-aware.

    If you want to run your operation in a separate worker thread you can use ThreadPool . where work items run asynchronously.

    Remember that, in STA, you cannot wait for the completion of a task. UI thread doesn't allow any kind of blocking. If any attempt to do so you will get an exception. Asynchronous operation doesn't return the result of operation immediately rather it returns the way of result. If you need the result immediately execute your code from a different worker thread.

    • Marked as answer by Mike Muir Friday, March 22, 2013 7:54 PM
    Friday, March 22, 2013 3:07 PM

All replies

  • The UI of a Windows Store app runs in a single-threaded apartment (STA). A task whose lambda returns either an IAsyncAction or IAsyncOperation will run in the STA, by default, if it is created from STA, unless you specify otherwise. If a task that doesn't return an IAsyncAction or IAsyncOperation, is not apartment-aware.

    If you want to run your operation in a separate worker thread you can use ThreadPool . where work items run asynchronously.

    Remember that, in STA, you cannot wait for the completion of a task. UI thread doesn't allow any kind of blocking. If any attempt to do so you will get an exception. Asynchronous operation doesn't return the result of operation immediately rather it returns the way of result. If you need the result immediately execute your code from a different worker thread.

    • Marked as answer by Mike Muir Friday, March 22, 2013 7:54 PM
    Friday, March 22, 2013 3:07 PM
  • Thanks!  Very helpful information.
    Friday, March 22, 2013 7:54 PM