c# - 异步方法不是等待
问题描述
在这个线程中,我可以使用事件来解决我在构造函数中等待异步方法的问题。在这种情况下,事件使用不带参数的委托。
但是现在我需要等待视图模型完成以等待异步方法可以继续。
我的主视图模型中有这段代码:
public void printMethod()
{
SecondViewModel mySeocViewModel = new SecondViewModel(myParameter);
SecondView mySecondView = new SecondView();
mySecondView.DataContext = mySeocViewModel;
//I have to wait until it finished to can print the user control
//The problem is that this point is reached before mySecondViewModel finish.
}
我的第二个视图模型中的代码:
public docFacturasViewModel(MyType parameter)
{
this.GetDataFromDatabaseEvent += OnGetDataFromDatabase;
GetDataFromDatabaseEvent(parameter);
}
public delegate void GetDataFromDatabaseEventHandler(MyType parameter);
public event GetDataFromDatabaseEventHandler GetDataFromDataBaseEvent;
private async void OnBuscarDatos(MyType paramter)
{
await getDataFromDatabaseAsync(parameter);
//Fill the data of the properties of the view model with the data from database
}
private async Task getDataFromDatabaseAsync(MyType parameter)
{
_myResult = (await getdataAsync(parameter)).FirstOrDefault();
}
如果我调试代码,它会以这种方式运行:
- 它到达主视图模型中的行以创建第二个视图模型。
- 在第二个视图模型中,它到达方法 OnGetDataFromDatabase 中的第一行,await。
- 主视图模型继续执行代码,因此它不会等待来自数据库的结果。
- 一段时间后,在第二个视图模型中,方法 OnGetDataFromDatabase 完成并在等待之后继续执行下一行代码。
我不明白为什么在第二个视图模型中代码不等到从数据库中获取数据,因为我使用 await 关键字并且所有代码都与我链接的帖子的情况相同开始。
谢谢。
编辑:
如果我使用第二个视图模型的构造函数:
Task.Run(() => buscarDatosAsync(paramFacturaParaImprimir)).Wait();
然后主视图模型等到第二个视图模型完成从数据库中获取数据。
但是当我在第一种情况下尝试这种方法时,在我链接并在另一篇文章中询问的情况下,该方法没有等待,所以我不明白为什么在一种情况下我必须使用委托并且在其他情况下,我可以使用任务并等待它完成。
解决方案
当async void
方法到达await
时,控制权返回给调用者。显然,当您需要操作结果来继续处理时,这不是最好的主意。除此之外,我不希望构造函数具有创建即发即弃任务的副作用。
如果您需要将数据结果作为对象构造的一部分,我建议您采用工厂方法:
private SecondViewModel()
{
}
public static async Task<SecondViewModel> CreateAsync(MyType parameter)
{
var result = new SecondViewModel();
result.SomeData = await getDataFromDatabaseAsync(parameter);
return result;
}
你会像这样使用它:
public async Task printMethod()
{
SecondViewModel mySeocViewModel = await SecondViewModel.CreateAsync(myParameter);
SecondView mySecondView = new SecondView();
mySecondView.DataContext = mySeocViewModel;
}
推荐阅读
- reactjs - React-hooks 和 d3.forceSimulation
- c# - 带有 JWT 的 API 尝试在没有 OWIN 的情况下进行身份验证
- python - 地理数据集 Python 上的特征提取
- visual-studio-2019 - 使用多个 TargetFrameworks 时的 OutputPath
- reactjs - 反应输入字段不允许用户输入
- python - 如何让 Selenium 识别按钮并单击它?
- google-cloud-platform - Google Speech to Text(语音识别)仅识别音频的前几秒
- sql - 无法从 vb.net 更新 MS Access 数据库
- java - 安装elasticsearch插件时Java版本检查器错误分析-拼音
- python - TypeError:“队列”对象不可迭代