Handling Windows Store App exceptions from GetFile

2019-04-10 10:03发布

问题:

I have a problem with the following code example:

    Windows::Storage::StorageFolder^ location = Package::Current->InstalledLocation;

    try
    {
        task<StorageFile^> GetFileTask(location->GetFileAsync(sn));

        GetFileTask.then([=](StorageFile^ file)
        {
            try
            {
                task<IBuffer^> ReadFileTask(FileIO::ReadBufferAsync(file));

                ReadFileTask.then([=](IBuffer^ readBuffer)
                { 
                    // process file contents here      
                });
            }
            catch(Platform::Exception^ ex)
            {
                // Handle error here
            }

        });
    }
    catch(Platform::Exception^ ex)
    {
        // Handle error here
    }

When using a filename that doesn't exist the function throws an exception:

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

I've been searching the internet and this exception breaks only when connected to the debugger. I'm using VS 2012. I've turned off all the relevant 'break on exception' but it still causes the debugger to break and non of my handlers are getting a chance to handle the exception.

If the file is missing I would expect the GetFileAsync method to throw a 'File doesn't exist' exception. Not sure why it keeps throwing the 'Invalid parameter' exception.

This is starting to bother me and I just can't find any known solution to this issue. Anyone have any ideas?

I'm going to try and change the method to not use the task<> code. Instead I'll call the GetFileAsync using 'await'. However I believe 'await' will just cause the calling thread to wait until the GetFileAsync has finished, which kind of defeats the point of asynchronous loading.

I'm wondering if this is a common issue with exception handling when using tasks.

Update:

OK, I've now found the solution:

    task<StorageFile^>( location->GetFileAsync(sn)).then([](StorageFile^ openedFile)
    {
        return FileIO::ReadBufferAsync(openedFile);
    }).then([](IBuffer^ readBuffer)
    {
        // Process file

    }).then([](task<void> t)
    {
        try
        {
            t.get();
        }
        catch(Platform::Exception^ e)
        {
            // Handle error
        }
    });

It seems there needs to be an extra 'then' condition added to the end of the chain to pick up the exception.