c# - 异步 if 被跳过并且函数跳转到结束
问题描述
我有这个异步功能:
private async Task<bool> ShowAboutToMatchAlert()
{
bool res = true;
if(Preferences.Get("WantSeeFirstMatchAlertAgain", true))
{
Device.BeginInvokeOnMainThread(async () =>
{
bool answer = await DisplayAlert("...");
if (answer)
{
Preferences.Set("WantSeeFirstMatchAlertAgain", false);
res = true;
}
else
{
res = false;
}
});
}
return res;
}
发生的情况是此功能显示警报。一旦用户选择一个选项(是或否),if(answer)
就会触发并根据输入给出结果。
但是,整个函数并没有等待结果,而是立即向前跳到最后的返回。所以总是true
被返回(因为函数是异步的)。
该函数本身必须是异步的,才能等待它,因为该函数也是从另一个异步函数调用的。
我怎样才能使这个功能await
成为if
一部分,而不仅仅是向前跳?
最简单的解决方案当然是让这个函数不是异步的,但是我不能再返回 "true" 或 "false" 但必须返回System.Threading.Task.Task<bool>
。所以这不是一个选择。
解决方案
如果Device.BeginInvokeOnMainThread
返回无效且无法等待 - 您可以使用它TaskCompletionSource
来实现您的目标。此类允许您获取Task
(可以等待)并手动设置它的完成结果。然后您的代码变为:
private Task<bool> ShowAboutToMatchAlert()
{
var tcs = new TaskCompletionSource<bool>();
if(Preferences.Get("WantSeeFirstMatchAlertAgain", true))
{
Device.BeginInvokeOnMainThread(async () => {
bool answer = await DisplayAlert("...");
if (answer)
{
Preferences.Set("WantSeeFirstMatchAlertAgain", false);
// signal completion with "true" result
tcs.SetResult(true);
}
else
{
// signal completion with "false" result
tcs.SetResult(false);
}
});
}
else {
tcs.SetResult(false);
}
return tcs.Task;
}
请注意,应该在所有tcs.SetResult
代码路径上调用(or SetCancelled
or ) ,包括异常,例如可能由(上面的示例中未显示)产生的异常,否则您可能会陷入令人讨厌的死锁。SetException
DisplayAlert
推荐阅读
- c++ - < 没有成员的类的运算符
- orange - 我是否以正确的方式在 Orange 中使用 PCA?
- node.js - 电子升级节点
- matlab - 如何根据实时(x,y,z)坐标在 Simulink 中制作 3d 图?
- forms - Shopify Omnisend 自定义 HTML 注册表单
- java - 如何在 GUI 应用程序中超出滚动窗格之外的滚动条
- node.js - Docusign 嵌入式签约仪式分步指南
- javascript - 如何下载用户创建的元素并给它一个事件?
- odoo-12 - 如何允许多个用户验证同一个采购订单
- machine-learning - 在机器学习中多次使用相同的输入(输出不同)是否可以接受?