Cannot handle exception in await/async method

PSchimmelPSchimmel DEMember ✭✭
edited February 2016 in Xamarin.Forms

Hi!
I started creating a XF app using a general PCL library and a Android project for the moment. The app communicates with a WebAPI to download/upload some data. The download function is in the Android specific part of the app and is generic:

public T DownloadData<T>(string controller, string action, int? id) { try { var url = getURL(controller, action, id); var client = (HttpWebRequest)WebRequest.Create(url); client.Method = "GET"; using (var response = client.GetResponse()) { using (var s = response.GetResponseStream()) { using (var reader = new StreamReader(s)) { var t = reader.ReadToEnd(); var result = JsonHelper.JsonDeserialize<T>(t); return result; } } } } catch (Exception ex) { OnMessage(ex.Message); HasError = true; return default(T); } }

Here is one sample how I call the function above. The call is made from the PCL library:

data.Machines = await Task.Run(() => provider.DownloadData<List<Machine>>("project", "machines"));

Everything works fine, but if there is an error while communicating with the server the exception cannot be handled. If an exception occurs the program enters the try..catch part of DownloadData but as soon as the method ends the app will exit immediately. I already tried to surround the method call with try..catch but no success. Before the app exits I can see the following information in my stack:

System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() in /Users/builder/data/lanes/2692/e98e9627/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143
System.Runtime.CompilerServices.AsyncMethodBuilderCore.AnonymousMethod__1(System.Runtime.ExceptionServices.ExceptionDispatchInfo state) in /Users/builder/data/lanes/2692/e98e9627/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1010
System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(System.Threading.QueueUserWorkItemCallback state) in /Users/builder/data/lanes/2692/e98e9627/source/mono/external/referencesource/mscorlib/system/threading/threadpool.cs:1291
System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Threading.QueueUserWorkItemCallback state, bool preserveSyncCtx) in /Users/builder/data/lanes/2692/e98e9627/source/mono/external/referencesource/mscorlib/system/threading/executioncontext.cs:581
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Threading.QueueUserWorkItemCallback state, bool preserveSyncCtx) in /Users/builder/data/lanes/2692/e98e9627/source/mono/external/referencesource/mscorlib/system/threading/executioncontext.cs:530
System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() in /Users/builder/data/lanes/2692/e98e9627/source/mono/external/referencesource/mscorlib/system/threading/threadpool.cs:1268
System.Threading.ThreadPoolWorkQueue.Dispatch() in /Users/builder/data/lanes/2692/e98e9627/source/mono/external/referencesource/mscorlib/system/threading/threadpool.cs:859
System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() in /Users/builder/data/lanes/2692/e98e9627/source/mono/external/referencesource/mscorlib/system/threading/threadpool.cs:1196

Posts

  • PSchimmelPSchimmel DEMember ✭✭

    After another sleepless night I discovered that the crash is not caused by the code line I originally thought.
    The problem is caused by the call of the OnMessage-Method which raises an message event. The message should be shown in the View using the following line in my ViewModel:
    dataManager.Message += (s, args) => MessagingCenter.Send<DownloadViewModel, DisplayAlertArgs>(this, "Message", new DisplayAlertArgs(Localize.GetString("Error"), args.Message, null, Localize.GetString("OK")));
    The view itself utilizes the MessagingCenter to display the message:
    protected override void OnAppearing() { MessagingCenter.Subscribe<DownloadViewModel, DisplayAlertArgs>(this.BindingContext as DownloadViewModel, "Message", async (sender, args) => await DisplayAlert(args.Headline, args.Message, args.Cancel), this.BindingContext as DownloadViewModel); base.OnAppearing(); }
    To me it doesn't help to understand why this is happening, but I have a hint now on how I could craft a workaround.

  • PSchimmelPSchimmel DEMember ✭✭

    Just discovered the solution. The problem was caused by the MessagingCenter I used to display the error message (OnMessage in the code above).

    After changing the following line in the view class:

    MessagingCenter.Subscribe<DownloadViewModel, DisplayAlertArgs>(this.BindingContext as DownloadViewModel, "Message", async (sender, args) => await DisplayAlert(args.Headline, args.Message, args.Cancel), this.BindingContext as DownloadViewModel);

    to

    MessagingCenter.Subscribe<DownloadViewModel, DisplayAlertArgs>(this.BindingContext as DownloadViewModel, "Message", (sender, args) => { Device.BeginInvokeOnMainThread(async () => { await this.DisplayAlert(args.Headline, args.Message, args.Cancel); }); }
    everything worked fine.

Sign In or Register to comment.