0

I have the method

public async Task doSomething()

Inside the method I have the code:

ShowSpinner();      

await System.Threading.Tasks.Task.Run(() =>
{
    try
    {
        getValue = value();
    }
    catch(Exception ex)
    {
    }
    finally
    {
        HideSpinner();
    }
    });

The ShowSpinner() and HideSpinner() are simply overlays to prevent the user from interacting with the screen and show a spinning wheel to indicate loading.

I am getting the error:

UIKit Consistency error: you are calling a UIKit method that can only be invoked from the UI thread.

I know that this is because of the HideSpinner(). How can I get around this consistency error?

Stephane Delcroix
  • 16,134
  • 5
  • 57
  • 85
jipot
  • 304
  • 3
  • 13
  • 34
  • 1
    the duplicate question has to do with WPF, not Xamarin. Same general concept, different answer. In Xamarin Forms, you need to use Device.BeginInvokeOnMainThread(), in Xarmarin iOS you would use InvokeOnMainThread() to force your UI updates to run on the UI thread. – Jason Jul 14 '15 at 19:15

1 Answers1

1

There are two things you can do here, the preferred method would be to await your task inside a try finally block, and the second less preferred method would be to wrap your HideSpinner(); in a RunOnUiThread.

preferred

ShowSpinner();
try
{    
    var val = await Task.Run(() => "foo");
    // for a little added performance, 
    // if val isn't being marshalled to the UI
    // you can use .ConfigureAwait(false);
    // var val = await Task.Run(() => "foo").ConfigureAwait(false);
}
catch { /* gulp */}
finally { HideSpinner(); }

less preferred

ShowSpinner();
await Task.Run(() =>
{
    try
    {
        var val = "value";
    }
    catch { /* gulp */ }
    finally
    {
        InvokeOnMainThread(() =>
        {
            HideSpinner();
        });

    }
});
Chase Florell
  • 46,378
  • 57
  • 186
  • 376