【问题标题】:C# Waiting for all Async tasks to complete when calling from a non-async methodC#从非异步方法调用时等待所有异步任务完成
【发布时间】:2020-08-05 13:43:35
【问题描述】:

我在 Xamarin Forms 项目的构造函数中有以下代码 - 我希望在调用 ShowPage() 方法之前完成每个步骤(它基本上是从 Web 服务加载数据) - 这会工作还是有更好的方法实现这一目标?

public MyTabbedPage()
 {
    ....
     Task.Run(async () => await vm1.LoadData();
     Task.Run(async () => await vm2.LoadData();
     Task.Run(async () => await vm3.LoadData();

     ShowPage();
     ....
 } ```

【问题讨论】:

标签: xamarin asynchronous xamarin.forms async-await task


【解决方案1】:

在同步函数中不正确地调用异步任务可能会出现问题,因为如果在任务中引发异常,它会抑制详细信息。因此,正确实施这一常见问题至关重要。

您可以使用位于 TaskHelpers.cs 下的 Helpers 文件夹中的 FireAndForget 助手,定义如下:

    public static async void FireAndForgetSafeAsync(this Task task, Action<Exception> handleErrorAction = null)
    {
        try
        {
            await task.ConfigureAwait(true);
        }
        catch (Exception ex)
        {
            handleErrorAction?.Invoke(ex);
        }
    }

然后,回到你的构造函数中,你可以这样做:

 public MyTabbedPage()
 {
     vm1.LoadData().FireAndForgetSafeAsync(HandleErrorInternal);
     vm2.LoadData().FireAndForgetSafeAsync(HandleErrorInternal);
     vm3.LoadData().FireAndForgetSafeAsync(HandleErrorInternal);
     ShowPage();
 }

 private void HandleErrorInternal(Exception ex)
 {
     DisplayAlertAsync("Error", ex.ToString(), "OK").FireAndForgetSafeAsync(HandleErrorInternal);
 }

【讨论】:

    【解决方案2】:

    始终尽量避免在构造函数中加载数据。只是一个好习惯。 放到 OnAppearing 方法中,改成 async。

            protected override async void OnAppearing()
        {
            await vm1.LoadData()
            await vm2.LoadData()
            await vm3.LoadData()
            base.OnAppearing();
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-15
      • 2023-04-08
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多