UIKITThreadAccessException from await Task.Run wit

2019-09-09 17:22发布

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?

1条回答
劫难
2楼-- · 2019-09-09 17:36

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();
        });

    }
});
查看更多
登录 后发表回答