InvalidOperationException When Working With IAsyncOperation<TResult>

November 27, 2014

WinRT introduced the concept of IAsyncOperation for working with Asynchrounous code. the IAsyncOperation is merely a representation of an Async Operation (a future in the computer science lingo) and as the same meaning as hte .NET System.Threading.Tasks.Task class, so its not suprising to see that you can convert IAsyncOpertion<TResult> to Task<TResult>

IAsyncOperation<int> asyncOperation=...; 
Task<int> task = operation.AsTask();

.NET Tasks has the Result property which gets the value of the async oprtation if it finished or wait till the value is available – this of course can cause the calling thread to freeze until the value is returned.

IAsyncOperation has something similar –  the GetResults() method – but unline the Task.Result, when calling it before the operation is completed you will get an InvalidOperationException

look at this code:

public string CameraModel
{
    get
    {
        try
        {
            var deviceInformationCollection = eInformation.FindAllAsync(DeviceClass.VideoCapture).GetResults();

            return string.Join(&quot;, &quot;, deviceInformationCollection.Select(information =&gt; information.Name).ToArray());
        }
        catch (InvalidOperationException)
        {
            return &quot;Unavailable&quot;;
        }

    }
}

this code is used inside a Windows 8.1 application and in most cases it worked fine but every once in a while it will cause the InvalidOperationException and return the “Unavailable” string.

There are a few options to solve this:

1. Convert it to an Async method that the will be awaited from the calling code – this is the recommended approach

2. Convert the IAsyncResult to a Task and use the Task.Result property – this will cause the task to wait for the IAsyncOperation result for us.

if you decide to work with the second option the code above will now be converted to:

public string CameraModel
{
    get
    {
        try
        {
            var deviceInformationCollection = eInformation.FindAllAsync(DeviceClass.VideoCapture).AsTask().Result;

            return string.Join(&quot;, &quot;, deviceInformationCollection.Select(information =&gt; information.Name).ToArray());
        }
        catch (InvalidOperationException)
        {
            return &quot;Unavailable&quot;;
        }

    }
}
Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*