简体   繁体   中英

Catch an async lambda exception

I am working on Windows 8 (using C#) and when using the async keyword there's a scenario where i can't seem to handle exceptions well.

The scenario involves launching an async lambda, posting it to run on the UI thread.
Exceptions that occur during the execution of the lambda code gets re-thrown on the calling thread, with no ability to catch them properly.

Example: this block of code is executed on some worker thread, and tries to schedule work on the UI thread:

await Window.Current.Dispatcher.RunAsync
        (CoreDispatcherPriority.Normal
         , async () =>
             {
               var result = await CurrentAppSimulator
                                  .RequestProductPurchaseAsync("product, true);
             }
        );

If the code inside the lambda expression throws an exception, the exception is not reposted back to the body of this method. Instead, it is being thrown by the SynchronizationContext or some similar mechanism, and i can't seem to catch it.

What i'd like to have is the ability to catch this exception from this body of code (the calling code).

Is this possible?

I think that if possible, you should not be doing this. The UI thread should be the one that's managing what happens on the background thread(s), not the other way around.

If you really do need this, you can use the overload of Task.Factory.StartNew() which lets you specify a TaskScheduler , along with Unwrap() to change the resulting Task<Task> into a simple Task :

await Task.Factory.StartNew(
    async () =>
        await CurrentAppSimulator.RequestProductPurchaseAsync("product", true),
    CancellationToken.None, TaskCreationOptions.None, scheduler)
    .Unwrap();

Alternatively, you could use await await :

await await Task.Factory.StartNew(
    async () =>
        await CurrentAppSimulator.RequestProductPurchaseAsync("product", true),
    CancellationToken.None, TaskCreationOptions.None, scheduler);

This means you need to pass the UI TaskScheduler (which you can get by calling TaskScheduler.FromCurrentSynchronizationContext() while you're on the UI thread) to this method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM