Windows RT store app dev – Inputs to / outputs from public and private async functions in C# and VB.NET

Windows RT (Windows 8.1) does not support exposing Task<T> on public methods and properties of class libraries (winmd files). As such, we are told to use IAsyncOperation<T> in place of Task<T>, since it provides similar functionality.

Here is an example of that in C#. The public function wraps the private one and thus allowed me to “await” my GetSomeData() function from another project that consumes this library.

private async Task<SomeOutput> GetSomeDataInternal(SomeInput inp)
{
SomeOutput ou = new SomeOutput();
using (var r = new StreamReader(await inp.OpenStreamForReadAsync()))
{
ou = await r.ReadToEndAsync();
}
return ou;
}

public IAsyncOperation<SomeOutput> GetSomeData(SomeInput inp)
{
return (IAsyncOperation<SomeOutput>)AsyncInfo.Run((System.Threading.CancellationToken ct) => GetSomeDataInternal(inp));
}

Calling the public function looks like this:

Dim myLib As MyLibrary.Utils = New MyLibrary.Utils()
Dim inp As New SomeInput()
Dim ou As SomeOutput = Await myLib.GetSomeData(inp)

All is well and good with a provider class library in C#. But that is not the case in pure VB.NET. I much prefer C# for complex things, but one must travel to where the river flows. So this had to be in VB.NET. The problem: when I attempted to do something similar to the above entirely in VB.NET, I encountered a COM error. So in order to make everything work, I devised the following code.

(Disregard that the output is gotten by accessing a property instead of calling a function; the main thing here is how to wrap the async private function in a public one and call it without COM errors and typecasting errors.)

Private _inp As SomeInput()
Public Property TheInput As SomeInput
Get
Return Me._inp
End Get
Set(value As SomeInput)
Me._inp = value
End Set
End Property

Public ReadOnly Property TheOutput As IAsyncOperation(Of SomeOutput)
Get
Return AsyncInfo.Run(Of SomeOutput)(Function(ct As System.Threading.CancellationToken) GetTheOutput())
End Get
End Property

Private Async Function GetTheOutput() As Task(Of SomeOutput)
Dim s As StorageFile = Await Windows.Storage.KnownFolders.PicturesLibrary.GetFileAsync(Me._inp)
Dim ou As New SomeOutput()
Await ou.SetSourceAsync(Await s.OpenReadAsync())
Return ou
End Function

So the above wrapped code was necessary to make Windows RT happy, since Task<T> may not be exposed publicly.
And I called the function (or in this case got the property) like so:

Dim myClass As New MyClass()
Dim inp As New SomeInput()
myClass.TheInput = inp

Dim ou As SomeOutput = Await myClass.TheOutput.AsTask()

AsTask() was necessary to cast the IAsyncOperation<T> back to Task<T> and make VB.NET happy.

So there are several things mentioned here:
– AsyncInfo.Run() in VB.NET
– Disentangling data from an async function in C# and VB.NET
– Avoiding the COM error
– Avoiding the typecasting error