我知道这个问题已经被问了很多次,但是我找不到适合我的答案。
我正在编写一个Xamarin Forms应用程序。在Android项目中,我需要重写这个方法:
public override bool OnJsConfirm(WebView view, string url, string message, JsResult result)
很遗憾,我不能将该方法设为异步。在该方法中,我想调用另外一个方法:
public static Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
{
var tcs = new TaskCompletionSource<bool>();
Device.BeginInvokeOnMainThread(async () =>
{
var result = await MainPage.DisplayAlert(title, message, accept, cancel);
tcs.SetResult(result);
});
return tcs.Task;
}
MainPage.DisplayAlert()
需要在UI线程上调用,我的方法可以确保这一点。
我已经尝试从同步的OnJsConfirm
方法中调用DisplayAlert
,使用了以下变体:
//bool success = UI.DisplayAlert(title, message, ok, cancel).Result; // hangs !!!
//bool success = UI.DisplayAlert(title, message, ok, cancel).WaitAndUnwrapException(); // hangs !!! WaitAndUnwrapException is in Nito.AsyncEx.Synchronous
//bool success = Nito.AsyncEx.AsyncContext.Run(() => UI.DisplayAlert(title, message, ok, cancel)); // hangs !!!
//bool success = TaskEx.Run(() => UI.DisplayAlert(title, message, ok, cancel)).Result; // hangs !!!
//bool success = Task.Run(() => UI.DisplayAlert(title, message, ok, cancel)).Result; // hangs !!!
//bool success = Task.Run(async () => await UI.DisplayAlert(title, message, ok, cancel)).Result; // hangs !!!
bool success = Task.Run(async () => await UI.DisplayAlert(title, message, ok, cancel).ConfigureAwait(false)).Result; // hangs !!!
我采用了Stephen Cleary在一个类似问题的答案中提出的使用Nito.AsyncEx的建议。
我也已经尝试将.ConfigureAwait(false)
添加到await MainPage.DisplayAlert(...)
中,但这也没有起作用。
当我在await MainPage.DisplayAlert
行设置断点时,在所有变体中都会触发,但当我按下F10时,VS2015停止在这个调用堆栈中:
没有异常,应用程序只是挂起了。
有谁知道怎样调用我的异步方法吗?
new Handler().Post(new Runnable(async () => //code));
- William Barbosa