等待任务与在任务中检查Task.Status

时间:2015-03-26 10:36:43

标签: c# asynchronous task-parallel-library task

问题描述:我得到了3个任务的控制台应用程序,它们在服务器上进行了一些计算(本地)。当我使用await Task.WhenAll()或替代Task.WaitAll()时,这些任务的计算时间与我在同步方法中运行这些任务的时间相似。我无望,所以我尝试使用while循环来检查任务状态。所以我的代码现在看起来像>

    public  void DoTask(PIServer server, AFTimeRange timeRange)
     {
        var timeRanges = DivideTheTimeRange(timeRange);
        Task[] tasksArray = new Task[3];
        watch.Start();
        Stopwatch watch = new Stopwatch();
        tasksArray[0] = (Task.Run(() => CalculationClass.AverageValueOfTagPerDay(server, timeRanges[0])));
        tasksArray[1] = (Task.Run(() => CalculationClass.AverageValueOfTagPerDay(server, timeRanges[1])));
        tasksArray[2] = (Task.Run(() => CalculationClass.AverageValueOfTagPerDay(server, timeRanges[2])));
        while (tasksArray[tasksArray.Count() - 1].Status != TaskStatus.RanToCompletion)
        { }
        //while (!Task.WaitAll(tasksArray,-1))
        //{}

        Task.WaitAll(tasksArray);
        //await Task.WhenAll(tasksArray); in case the method got async keyword
        watch.Stop();
        Console.WriteLine("Final elapsed time is" + watch.Elapsed);
      }

 public static void AverageValueOfTagPerDay(PIServer server, AFTimeRange timeRange)
    {
        Console.WriteLine("Thread in AVERAGE()> {0} task> {1}", Thread.CurrentThread.ManagedThreadId,Task.CurrentId);

        var listOfAverage = new Dictionary<PIPoint, AFValues>();
        PIPagingConfiguration config = new PIPagingConfiguration(PIPageType.TagCount, 1);
        PIPointList pointList = new PIPointList();
        pointList.Add(PIPoint.FindPIPoint(server, "HugeTestingTag_ADracka"));
        AFTimeSpan timeSpan = new AFTimeSpan(days: 1);
            Stopwatch s = new Stopwatch();
            s.Start();
            var listResults = pointList.Summaries(timeRange, timeSpan, OSIsoft.AF.Data.AFSummaryTypes.Average, OSIsoft.AF.Data.AFCalculationBasis.TimeWeighted,
                OSIsoft.AF.Data.AFTimestampCalculation.Auto, config);
            s.Stop();
            Console.WriteLine("Elapsed Time >{0} for task>{1}", s.Elapsed,Task.CurrentId);
            foreach (var item in listResults)
            {   
                AFValues values = item[OSIsoft.AF.Data.AFSummaryTypes.Average];
                PIPoint point = values.PIPoint;
                listOfAverage[point] = values;
            }
        Program.Show(listOfAverage);
    }

我在AverageValueOfTagPerDay()方法中测量计算时间。使用此代码我可以实现我的目标(计算平均快50%)但我不知道为什么。我也尝试使用while循环Task.WaitAll()方法,但这也没有帮助。 那么为什么在while循环中检查Task.Status使我的任务更快,然后方法Task.WhenAll ???我不明白。

  

结果没有 WHILE循环:While loop is commented   结果 WHILE循环:enter image description here

更新2

  

在AverageValueOfTagPerDay中使用Thread.Sleep(1000)的结果:enter image description here   如果我评论WHILE循环经过的时间有点快:1.04

1 个答案:

答案 0 :(得分:0)

while (tasksArray[tasksArray.Count() - 1].Status != TaskStatus.RanToCompletion)
{ }

它只检查最后一个任务,你必须循环整个数组。最后一项任务可能会更快,因为它可能在最小范围内工作。

尝试以下方法:

while (tasksArray.Any(t => t.Status != TaskStatus.RanToCompletion))
{ }