Pre*_*ott 6 c# synchronization closures stopwatch task-parallel-library
我正在循环运行并以下列方式开始执行任务:
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);
}
Run Code Online (Sandbox Code Playgroud)
在我的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);
}
Run Code Online (Sandbox Code Playgroud)
当我遍历我的列表时,myMsg
ElaspedMilliseconds似乎完全是加法的 - 第一个上的ElaspedMilliseconds可能是300,但最后一个可能是50000(50秒) - 这实际上是整个事情所需的大致时间运行(由另一个计时器测量).
编辑:
哎呀,我一开始也很困惑。
问题是它看起来只是累加(累积),因为 ElapsedTime 值始终仅按递增顺序输出。
因此,如果我有,如下面的演示所示,按启动顺序:
那么结果会按照初始顺序出现在输出中 - 始终按照任务持续时间递增的顺序:
以下是控制台应用程序的输出:
from DoSomething 6043
from main 6043
from DoSomething 8057
from main 8057
from DoSomething 10058
from main 10058
Run Code Online (Sandbox Code Playgroud)
原因很明显 - 因为更快的任务总是在更长(更耗时)的任务之前完成并输出。
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) );
*/
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1774 次 |
最近记录: |