我有一个类似下面的方法
internal static ProgressDialogResult Execute(Window owner, string label, Action operation, ProgressDialogSettings settings)
{
return ExecuteInternal(owner, label, (object)operation, settings);
}
用于根据任务完成情况显示进度条。 我正在调用上面的方法,如下所示
int count = soilData.Count;
var result = ProgressDialog.Execute(this, "Loading data", async () => {
for (int i = 1; i <= count; i = i + 1000)
{
await soilDataMigration.MigrateSoilData(soilData.GetRange(i, i + 1000 >= count ? count - i : 1000));
}
}, ProgressDialogSettings.WithSubLabel);
if (result.OperationFailed)
MessageBox.Show("Soil data upload failed failed.");
else
MessageBox.Show("Soil data successfully executed.");
soilData.Clear();
但是当我尝试执行相同的操作时,它突然从lambda中出来并开始执行if语句。 但是我的预期行为是只有当我在循环内完成所有异步操作时,控制才会退出此lambda。
我在stackoverflow中检查了这个问题 Is there a way to run async lambda synchronously?
但不幸的是,该软件包与.net版本4.5.2不兼容
有人可以帮我解决这个问题吗?
答案 0 :(得分:1)
实际上你有两个选择:
1)重构所有与async..await
兼容的调用,例如
internal static async System.Threading.Task<ProgressDialogResult> Execute(Window owner, string label, Func<System.Threading.Task> operation, ProgressDialogSettings settings)
{
return await ExecuteInternal(owner, label, (object)operation, settings);
}
internal static async System.Threading.Task<ProgressDialogResult> ExecuteInternal(Window owner, string label, Func<System.Threading.Task> operation, ProgressDialogSettings settings)
{
// do whatever
await operation();
return //whatever;
}
然后像这样消耗它:
int count = soilData.Count;
var result = await ProgressDialog.Execute(this, "Loading data", async () => {
for (int i = 1; i <= count; i = i + 1000)
{
await soilDataMigration.MigrateSoilData(soilData.GetRange(i, i + 1000 >= count ? count - i : 1000));
}
}, ProgressDialogSettings.WithSubLabel);
if (result.OperationFailed)
MessageBox.Show("Soil data upload failed failed.");
else
MessageBox.Show("Soil data successfully executed.");
soilData.Clear();
和
2)只需更改您传递的await
方法即可
soilDataMigration.MigrateSoilData(soilData.GetRange(i, i + 1000 >= count ? count - i : 1000)).GetAwaiter().GetResult();
通常,选项1)更好,因为它清楚地表示意图并协调您拥有的代码。选项2)更像是一种解决方法。