我知道这个问题已经问了很多次了,但我找不到一个对我有用的答案。
我在写一个Xamarin表单应用程序。在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;
}需要在UI线程上调用MainPage.DisplayAlert(),这是我的方法所确保的。
我已经尝试使用以下变体从同步DisplayAlert方法调用我的OnJsConfirm:
//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的Nito.AsyncEx中得到了使用这个答案的建议,并提出了类似的问题。
我也尝试过将.ConfigureAwait(false)添加到await MainPage.DisplayAlert(...)中,但这也不起作用。
当我在await MainPage.DisplayAlert行设置一个断点时,除了最后两个变体之外,所有的断点都会被击中,然后按下F10,VS2015就停止了这个调用堆栈:

当然也不例外。应用程序就挂起来了。
有谁知道,我怎么能调用我的异步方法?
发布于 2016-03-31 15:03:27
如果要处理确认对话框,则OnJsConfirm的返回值仅指示。因此,您需要返回true并异步执行其余的操作。如果您的DisplayAlert返回,您可以根据任务的结果在JsResult上调用Confim()或Cancel()。
public override bool OnJsConfirm(WebView view, string url, string message, JsResult result)
{
DisplayAlert("Really?", message, "OK", "Cancel").ContinueWith(t => {
if(t.Result) {
result.Confirm();
}
else {
result.Cancel();
}
});
return true;
}
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;
}https://stackoverflow.com/questions/36335859
复制相似问题