Xamarin.Forms - BeginInvokeOnMainThread异步操作
问题描述:
我熟悉有关使用Device.BeginInvokeOnMainThread更新UI线程上的UI元素的规则,但是我有一个操作需要在UI线程上运行,该线程实际上是一个任务。Xamarin.Forms - BeginInvokeOnMainThread异步操作
例如,XLabs.Forms.Mvvm上的Push/PopAsync方法似乎在iOS上行为不正确,除非它们在UI线程上调用。在Acr.UserDialogs库中还有另外一个例子,用于显示Toast等。
我知道制作一个Action异步基本上是创建一个异步void lambda,并且在异常的情况下运行创建死锁的风险,显然我不希望发生这种情况。
有没有人有一个解决方案在UI线程上执行异步操作,不涉及将Action标记为异步?
答
只要确保你在你的操作中处理异常,你应该没问题。您描述的问题发生在不处理异常时。下面是从主线程运行异步方法的一个非常简单的例子。
private void Test()
{
Device.BeginInvokeOnMainThread(SomeMethod);
}
private async void SomeMethod()
{
try
{
await SomeAsyncMethod();
}
catch (Exception e) // handle whatever exceptions you expect
{
//Handle exceptions
}
}
private async Task SomeAsyncMethod()
{
await Navigation.PushModalAsync(new ContentPage());
}
答
删除该在这里如果有人想等待它必须在主线程上执行的动作结束
public static class DeviceHelper
{
public static Task RunOnMainThreadAsync(Action action)
{
var tcs = new TaskCompletionSource<object>();
Device.BeginInvokeOnMainThread(
() =>
{
try
{
action();
tcs.SetResult(null);
}
catch (Exception e)
{
tcs.SetException(e);
}
});
return tcs.Task;
}
public static Task RunOnMainThreadAsync(Task action)
{
var tcs = new TaskCompletionSource<object>();
Device.BeginInvokeOnMainThread(
async() =>
{
try
{
await action;
tcs.SetResult(null);
}
catch (Exception e)
{
tcs.SetException(e);
}
});
return tcs.Task;
}
}