5

我在一个循环中运行,并以下列方式拉开任务:秒表在任务似乎是所有任务的添加剂,要测量的只是任务间隔

var iResult = new List<Task>(); 
foreach(var i in myCollection) 
{ 
    var task = Task.Factory.StartNew(() => 
        DoSomething(), TaskCreationOptions.LongRunning); 
    task.ContinueWith(m => myResponseHandler(m.Result)); 
    iResult.Add(task); 
} 

在我的DoSomething()方法,我有一个计时器:

public static myMsg DoSomething() 
{ 
    var timer = System.Diagnostics.Stopwatch.StartNew(); 
    DoLongRunningTask(); //If it matters this hits a REST endpoint (https) 
    timer.Stop(); 

    return new myMsg(timer.ElaspedMilliseconds); 
} 

当我通过我的myMsg的的ElaspedMilliseconds的列表迭代似乎是完全添加剂 - 在第一个的ElaspedMilliseconds可能是300,但最后一个可能是50000(50秒), - 这实际上是一个整个事情需要运行的时间(由另一个计时器测量)。

+1

Updated [my answer](http://stackoverflow.com/a/16259019/200449)。它只是看起来似乎是累加性的,因为ElapsedMilliseconds值总是以递增顺序输出 - 按任务完成顺序(按任务持续时间顺序),这不是任务启动的顺序 – 2013-04-28 07:55:02

回答

2

编辑:

哎呀,我也第一次感到困惑。

问题是它只看起来很敏感(累计),因为ElapsedTime值总是以递增的顺序输出。

所以,如果我有,下面我的演示,在启动顺序:

  • 10秒(10000毫秒)1日发布任务的持续时间,
  • 8秒的第二个任务的工期(8 000毫秒),
  • 6秒(6 000毫秒)的3D任务的持续时间,

然后将结果显示在输出出初始顺序的 - 总是increasi的顺序任务的NG时间:

  • 第一输出:在推出了3D任务的持续时间(6秒的持续时间)
  • 在输出第2:第二个推出任务的持续时间(8秒的持续时间)
  • 的3D(最后)输出:第一发射任务的持续时间(10秒的持续时间)

这是从下面的控制台应用程序的输出:

from DoSomething 6043 
from main 6043 
from DoSomething 8057 
from main 8057 
from DoSomething 10058 
from main 10058 

这很明显,为什么 - 因为更快的任务总是在更长时间(更耗时)的任务之前完成并输出。

using System; 
using System.Collections.Generic; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Diagnostics; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     var iResult = new List<Task>(); 
     for (int i=5; i>2; i--) 
     { 
     int load = i; 
     var task = Task.Factory.StartNew(() => 
         DoSomething(load), TaskCreationOptions.LongRunning); 
     //following commented lines do NOT change the behavior in question 
     task.ContinueWith(m => Console.WriteLine("from main "+m.Result)); 
     //iResult.Add(task); 
     } 
     Console.ReadLine(); 
    } 

    //public static myMsg DoSomething() 
    public static long DoSomething(int load) 
    { 
     Stopwatch timer = System.Diagnostics.Stopwatch.StartNew(); 

     //usage of either prev or following 2 lines produce the same results 
     //Stopwatch timer = new Stopwatch(); //instead of prev .StartNew(); 
     //timer.Start();// instead of prev .StartNew(); 

     Console.WriteLine("***Before calling DoLongRunningTask() " 
       + timer.ElapsedMilliseconds); 
     Console.WriteLine("GetHashCode "+timer.GetHashCode()); 

     DoLongRunningTask(load); 
     timer.Stop(); 

     long elapsed = timer.ElapsedMilliseconds; 
     Console.WriteLine("from DoSomething "+ elapsed); 

     return elapsed;//return new myMsg(timer.ElaspedMilliseconds); 
    } 

    public static void DoLongRunningTask(int load) 
    { 
     Thread.Sleep(2000*load); 
     /******************* another variant of calculation intensive loading 
      load = load; 
      double result = 0; 
      for (int i = 1; i < load*100000; i++) 
        result += Math.Exp(Math.Log(i)); 
     */ 
    } 
    } 
} 
+1

为什么负载会在任务间改变?他们应该持续相同的时间。 – LightStriker 2013-04-28 13:40:54

2

最有可能发生的一件事是DoLongRunningTask()可能不是正确的多线程,这意味着一个任务在第一个完成之后运行等等。每个任务都有自己的计时器,它们都在同一时间开始某处(或者线程分配给任务),但是长时间运行的任务将它们全部抵消掉了。

您从来没有无限的线程池和任务处理谁获得线程和时间。

关于LongRunning:。

“这不是一个特定的长度本身如果你产生了很多任务,LongRunning是不适合他们。如果你生成一个或两个任务将持续相对于你的应用程序的生命周期来说,相当长的一段时间,那么LongRunning是需要考虑的事情。一般来说,除非你发现你真的需要它,否则不要使用它。在封面之下,它会导致更多的线程因为它的目的是允许ThreadPool继续处理工作项目,即使一个任务正在运行很长一段时间;如果该任务在池中的线​​程中运行,该线程将无法服务其他任务,通常只使用LongRun如果你通过性能测试发现不使用它会导致其他工作处理的长时间延迟。“ - 斯蒂芬Toub

+0

只是为了详细说明,如果'DoLongRUnningTask ()'锁定共享数据段时,定时器*很可能是加法正确的,因为每个定时器都启动,然后暂停直到前一个完成。尝试用一个简单的延迟任务替换它,看看是否得到正确的时间。 – Bobson 2013-04-26 16:40:21

+0

@Bobson,[我正在复制相同的](http://stackoverflow.com/a/16259019/200449)没有任何锁在数据 – 2013-04-28 03:19:09

+0

@LightStriker数据,所以如果DoLongRunningTask()可能不是多线程正确“,即使它重用了相同的专用线程(最有可能是因为TaskCreationOptions.LongRunning)。即使当我明确创建新实例'Stopwatch timer = new Stopwatch();'或在使用它之前重置时间,'timer.ElapsedMilliseconds'值将累积/递增到先前的实例 – 2013-04-28 03:20:23