如何连续使用加载微调器来执行两个异步任务

时间:2014-12-16 10:40:19

标签: c# ios asynchronous async-await loading

目前,我有两个独立的异步任务,可以发出不同的Web请求。执行异步任务时,会显示加载微调器。现在我应该向第一个添加第二个异步任务,其中第二个依赖于第一个。

我的主要问题是加载微调器,同时总结了两个异步调用。 Hide()上有一个淡出动画,设置为0.5秒。因此,旋转器在短时间内显示两次,看起来有点难看。如果我跳过动画,我会得到一个闪烁效果。

也许我错了,我应该转向正常的同步请求,但我不想阻止UI线程。我不知道应该搜索什么。这就是我目前所做的,是一个简化版本:

public async void showList()
{
    List<Car> carList = new List<Car>();
    carList = await GetCarListTask();
    List<string> manufacturers = extractIDs(carList);
    List<Manufacturer> manufacturerList = await GetManufacturerListTask(manufacturers);
    Table.Show(carList, manufacturerList);
}

public async Task<List<Car>> GetCarListTask(){
    LoadingOverlay loadingOverlay = new LoadingOverlay ();
    List<Car> carList = new List<Car>();

    try{
        loadingOverlay.Show();
        carList = await Task.Run(() => manager.GetCarList());
        loadingOverlay.Hide();
        return carList;
    }
    catch(Exception ex)
    {
        alert.Show("Something went wrong");
        loadingOverlay.Hide();
    }

    return carList;
}

public async Task<List<Manufacturer>> GetManufacturerListTask(List<string> manufacturerID){
    LoadingOverlay loadingOverlay = new LoadingOverlay ();
    List<Manufacturer> manufacturerList = new List<Manufacturer>();

    try{
        loadingOverlay.Show();
        manufacturerList = await Task.Run(() => manager.GetManufacturerList(manufacturerID));
        loadingOverlay.Hide();
        return manufacturerList;
    }
    catch(Exception ex)
    {
        alert.Show("Something went wrong");
        loadingOverlay.Hide();
    }

    return manufacturerList;
}

如您所见, LoadingOverlay()是为每个请求独立创建的,并取决于当前视图。 Show()实际上是this.NavigationController.View.InsertSubviewBelow(loadingOverlay,this.NavigationController.NavigationBar)的替代品,唯一的中心位置是 AppDelegate ,但我不认为它可以访问我使用的每个导航控制器(模态视图,弹出窗口......)。

我该如何解决这个问题?

修改

目前我没有显示第二个加载微调器。如果用户比请求更快,那会发生什么呢?那么我应该让第二个调用同步吗?

我想到的另一个选择是重新设计LoadingOverlay(),使闪烁不会那么明显。最好的解决方案是有一个加载类,它一直显示加载微调器,直到所有连续的请求都完成。但我不知道这样一个集中的实例会是什么样子。一个简单的解决方案是将两个调用汇总到一个方法中,但您必须知道返回类型。

1 个答案:

答案 0 :(得分:4)

我不明白为什么你不能只将显示/隐藏逻辑移动到调用方法:

public async Task ShowListsAsync()
{
  LoadingOverlay loadingOverlay = new LoadingOverlay ();
  loadingOverlay.Show();
  try
  {
    List<Car> carList = await Task.Run(() => manager.GetCarList());
    List<string> manufacturers = extractIDs(carList);
    List<Manufacturer> manufacturerList = await Task.Run(() => manager.GetManufacturerList(manufacturers));
    Table.Show(carList, manufacturerList);
  }
  catch
  {
    alert.Show("Something went wrong");
  }
  finally
  {
    loadingOverlay.Hide();
  }
}

也许这个例子过于简单,并且有一些原因不适用。

另外,作为旁注:

  

我有两个独立的异步任务,可以发出不同的Web请求

Web请求本质上是异步的。如果您使用HttpClient之类的内容,那么从GetCarList公开GetManufacturerList / manager的异步版本应该很简单。这样就无需Task.Run

List<Car> carList = await manager.GetCarListAsync();
List<string> manufacturers = extractIDs(carList);
List<Manufacturer> manufacturerList = await manager.GetManufacturerListAsync(manufacturers);