編集:
おっと、私も最初戸惑いました。
問題は、ElapsedTime 値が常に昇順でのみ出力されるため、相加的 (累積的) にしか見えないことです。
したがって、以下のデモのように、起動する順序があるとします。
- 最初に起動されたタスクの持続時間 10 秒 (10000 ミリ秒)、
- 2 番目のタスクの持続時間 8 秒 (8 000 ミリ秒)、
- 3D タスクの持続時間 6 秒 (6 000 ミリ秒)、
その後、結果は最初の順序から外れて出力に表示されます-常にタスクの期間が長くなる順序で:
- 最初の出力: 3D 起動タスクの期間 (6 秒の期間)
- 出力の 2 番目: 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) );
*/
}
}
}