等待完成Async lambda表达式

时间:2017-12-27 03:07:58

标签: c# wpf asynchronous lambda

我有一个类似下面的方法

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不兼容

有人可以帮我解决这个问题吗?

1 个答案:

答案 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)更像是一种解决方法。