UIKITThreadAccessException from await Task.Run with a try-catch-finally block

混江龙づ霸主 提交于 2019-12-12 00:17:34

问题


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:


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

    }
});


来源:https://stackoverflow.com/questions/31412984/uikitthreadaccessexception-from-await-task-run-with-a-try-catch-finally-block

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!