3

So far I could make a delegate type, for example:

// Can't use Task in WinRT interface and TypedEventHandler doesn't work with async await
public delegate IAsyncOperation<string> AsyncEventHandler(object sender, object args);

And then expose in WinRT object like so:

public AsyncEventHandler OnMyEvent { get; set; }

In the WinRT object I would call it like this:

if (OnMyEvent != null)
{
    var result = await OnMyEvent.Invoke(this, someArgs);
    // Do something with the result...
}

And the client code consuming the WinRT object could do this:

instanceOfWinRTObject.OnMyEvent = OnCalledBackFromWinRT;

But because the delegate returns an IAsyncOperation we need to do some wrapping:

private async Task<string> OnCalledBackFromWinRTAsync(object sender,
        object args)
{
    return await GetSomeStringAsync(args);
}

private IAsyncOperation<string> OnCalledBackFromWinRT(object sender, object args)
{
    return OnCalledBackFromWinRTAsync(sender, args).AsAsyncOperation();
}

It just feels like there must be a cleaner way to achieve this.

Johnny Haddock
  • 415
  • 3
  • 11

1 Answers1

0

Here is an alternative prompted by Peter Torr's comment.

// Custom event args class
public sealed class MyEventArgs
{
    public string Result;
    public Deferral Deferral;
}

// Declare the event handler on the WinRT component
public event TypedEventHandler<object, MyEventArgs> OnSuspendingEvent;

Then in the WinRT component you could invoke the event like this:

if (OnSuspendingEvent != null)
{
    var tcs = new TaskCompletionSource();
    using (var deferral = new Deferral(() => tcs.SetResult(true)))
    {
        var myArgs = MyEventArgs();
        myArgs.Deferral = deferral;
        OnSuspendUnloading.Invoke(this, myArgs);
        await tcs.Task;
        DoSomethingWithResult(args.Result);
    }
}

And finally in the client code add a handler like so:

instanceOfWinRTObject.OnSuspendingEvent += async (sender, args) =>
{
    var deferral = args.Deferral;
    try
    {
        // Client does some async work with a result
        args.Result = await GetSomeStringAsync(args);
    }
    finally
    {
        deferral.Complete();
    }
}
Johnny Haddock
  • 415
  • 3
  • 11