【问题标题】:Moment of multiple tasks end while they return different objects多个任务在返回不同对象时结束的时刻
【发布时间】:2018-03-26 00:29:32
【问题描述】:

我有 5 个这样的任务:

private async Task<List<Places>> GetPlaces()
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    var list5 = await GetPlacesTask();
    sw.Stop();
    Testowybox3.Text = sw.Elapsed.ToString()+" get places times";
    return list5;
}
private async Task<List<Categories>> GetCategories()
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    var list5 = await GetCategoriesTask();
    sw.Stop();
    Testowybox2.Text = sw.Elapsed.ToString()+" get categories times";
    return list5;
}

它们的返回值不同,例如我的第二个任务:

 private async Task<EventsInstance[]> GetDetailedData()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            list4 = await GetDetailedDataTask();
            List<EventsListPrint> lista = new List<EventsListPrint>();
            foreach (var VARIABLE in list4)
            {
                lista.Add(new EventsListPrint() { Date = string.Format("{0:dd.MM.yyyy}", VARIABLE.startDate.Date), Time = VARIABLE.startDate.TimeOfDay.ToString(), Category = VARIABLE.categoryId.ToString(), Where = VARIABLE.organizer.designation, What = VARIABLE.name });
            }
            fruitdatagrid2.ItemsSource = lista;
            sw.Stop();
            Testowybox.Text = sw.Elapsed.ToString()+" get detailed data times";


            return list4;
        }

        private async Task<List<Organizers>> GetOrganizers()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            var list5 = await GetOrganizersTask();

            sw.Stop();
            Testowybox4.Text = sw.Elapsed + " get orgzanizers times";
            return list5;
        }

他们正在从网络解析 Json。我正在像这样从他们那里收集数据:

            var DetailedDataList = await GetDetailedData();
            var CategoriesList = await GetCategories();
            var PlacesList = await GetPlaces();
            var OrganizersList = await GetOrganizers();
            var EventsList = await GetEvents();

我如何确保它们都已完成?我试过了:

   Task.WhenAll(GetDetailedData(), GetCategories(), GetPlaces(), GetOrganizers(), GetEvents());

但我似乎无法检索值。我真正想要实现的是创建能够知道成功完成任务的方法,然后在我的 WPF GUI 中对这些数据进行操作。我也许可以将它们连在一起,但我只是不知道该怎么做。就我使用返回的列表之一而言,一切正常。当尝试使用另一个列表在一个列表上执行 linq 时,有可能另一个列表尚未准备好,它只会让我的应用程序崩溃。

【问题讨论】:

  • await Task.WhenAll了吗?
  • 是的,我做到了。仍然什么都没有,访问返回值时仍然必须使用等待。

标签: c# asynchronous parallel-processing async-await task


【解决方案1】:

当您await Task.WhenAll时,当线路恢复时,您可以放心,提供的任务将处于完成状态。

var detailedDataTask = GetDetailedData();
var categoriesTask = GetCategories();
//etc
await Task.WhenAll(detailedDataTask, categoriesTask); //etc

但是,包含任务 (detailedDataTask) 的变量仍然是 Task&lt;T&gt;。不是他们包装的类型,T

我们如何解开已完成的任务?

我们可以(不直观,但最好)await 完成的任务:

var detailedData = await detailedDataTask;

或者(因为我们知道任务已经完成)我们可以直接去.Result属性而不用担心阻塞......

var detailedData = detailedDataTask.Result;

由于运行时解开您的异步异常时会发生额外的魔法,您可能应该更喜欢awaiting。

【讨论】:

  • await 在异常处理方面与Result 的行为略有不同。
  • @CoryNelson 是的。这里有更多信息:stackoverflow.com/a/24657079/14357
  • 当我尝试使用时:await Task.WhenAll(GetDetailedData()); varDetailedDataList = GetDetailedData().Result;它正在努力崩溃。
  • @needtobe 你打电话给GetDetailedData() 两次,它运行了两次。第一次轮到你等待它。第二轮你在完成之前调用.Result。我上面的示例将任务存储在变量中是有原因的。
  • 那么我怎样才能从一个 Task.WhenAll(GetDetailedData()); 中返回我的值?当我使用只是 await GetDetailedData().Result;它仍然令人遗憾地崩溃。
猜你喜欢
  • 2020-05-06
  • 1970-01-01
  • 2020-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多