locked
Exception when calling StorageFile::OpenAsync

    Question

  • This code throws exception:

    create_task(m_IStorageFile->OpenAsync(Windows::Storage::FileAccessMode::Read)).then([this](task<Windows::Storage::Streams::IRandomAccessStream^> task)
     {
      m_RandomAccessStream = task.get();
      m_Size = m_RandomAccessStream->Size;
      m_length = m_Size;
      m_isReady = true;
     }).wait();

    Exception is:
    Unhandled exception at 0x605A4E43 (msvcr110d.dll) in app_rt.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.

    Call stack:
    > msvcr110d.dll!_invoke_watson(const wchar_t * pszExpression, const wchar_t * pszFunction, const wchar_t * pszFile, unsigned int nLine, unsigned int pReserved) Line 131 C++
      vccorlib110d.dll!__abi_FailFast() Line 18 C++
      app_rt.exe!Windows::UI::Xaml::RoutedEventHandler::[Windows::UI::Xaml::RoutedEventHandler::__abi_IDelegate]::__abi_Windows_UI_Xaml_RoutedEventHandler___abi_IDelegate____abi_Invoke(Platform::Object ^ __param0, Windows::UI::Xaml::RoutedEventArgs ^ __param1) C++
      Windows.UI.Xaml.dll!5fae1011() Unknown
    .....

    Last messages in output window:
    First-chance exception at 0x77004B32 in app_rt.exe: Microsoft C++ exception: Concurrency::invalid_operation at memory location 0x037AE8D0.
    Unhandled exception at 0x605A4E43 (msvcr110d.dll) in app_rt.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.

    .then() is never executed and I can't catch this exception.

    File is accessible and readable.
    But exception is not thrown always, it seems at random. When I re-run application it works, with the same file.
    This is not called from UI thread, so it should be ok to call .wait ?
    But even without .wait it's the same, altough it seems to happen less frequently at least in debug mode.

    Could someone please tell me why this code throws exception ?

    Thursday, January 17, 2013 9:49 PM

Answers

  • *.wait();

    Check whether you are executing your code from a worker thread or not, because  UI thread does not allow any blocking. As Windows Store Apps are completely asynchronous and UI always remains responsive, blocking or waiting is not expected here. You may use call-back mechanism in this context.

    *.get();
    If you are executing your code from UI thread you should use task chain for maintaining sequence, because UI thread does not allow any blocking for synchronization.

    task chains, -> myTask.then(…).then(…).then(…);

    If you are executing your code in a different worker thread, you may try like following sample
    create_task( fileHandle->OpenAsync(Windows::Storage::FileAccessMode::Read) ).then(
            [&taskResult] (task<void> previousTask)
        {
            try
            {
                previousTask.get();  // get exception
            }
            catch (Exception^ exception)
            {
                taskResult = exception->HResult;
            }
        }).get();         // Also try .wait()
    If you have multiple asynchronous operations, try to use task chain.

    • Marked as answer by Dereck S Friday, January 18, 2013 9:57 AM
    Friday, January 18, 2013 3:46 AM

All replies

  • If it works sometimes but not others it could possibly be you are not closing the file after use.

    Also, I cant see which folder you are trying to access.

    What is the file name your trying to access ?


    n.Wright

    Thursday, January 17, 2013 11:02 PM
  • *.wait();

    Check whether you are executing your code from a worker thread or not, because  UI thread does not allow any blocking. As Windows Store Apps are completely asynchronous and UI always remains responsive, blocking or waiting is not expected here. You may use call-back mechanism in this context.

    *.get();
    If you are executing your code from UI thread you should use task chain for maintaining sequence, because UI thread does not allow any blocking for synchronization.

    task chains, -> myTask.then(…).then(…).then(…);

    If you are executing your code in a different worker thread, you may try like following sample
    create_task( fileHandle->OpenAsync(Windows::Storage::FileAccessMode::Read) ).then(
            [&taskResult] (task<void> previousTask)
        {
            try
            {
                previousTask.get();  // get exception
            }
            catch (Exception^ exception)
            {
                taskResult = exception->HResult;
            }
        }).get();         // Also try .wait()
    If you have multiple asynchronous operations, try to use task chain.

    • Marked as answer by Dereck S Friday, January 18, 2013 9:57 AM
    Friday, January 18, 2013 3:46 AM
  • File is choosen with FilePicker:

    FileOpenPicker^ openPicker = ref new FileOpenPicker();
    concurrency::create_task(openPicker->PickSingleFileAsync()).then([this](StorageFile^ file)
        {
            if (file)
            {
                openFile(file);
            }
            else
            {
                OutputDebugString(L"PickFile FAILED");
            }
        });

    But it seems it was actually problem calling .wait from UI thread.
    Friday, January 18, 2013 9:56 AM
  • OK I checked and it seems I was calling this from UI thread.
    I was wrong in first post, sorry.
    I was testing something and moving code around and in debugger it says Worker thread, but I checked and it's the same thread that OnClick event executes so it's probably UI thread.
    Now it works. Thanks.

    Friday, January 18, 2013 9:57 AM