问题
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