Csharp/C#教程:任务中的秒表似乎是所有任务的附加,想要测量任务间隔分享


任务中的秒表似乎是所有任务的附加,想要测量任务间隔

我正在循环运行并以下列方式启动任务:

var iResult = new List(); 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的列表时, myMsg似乎完全是加法的 – 第一个上的ElaspedMilliseconds可能是300,但最后一个可能是50000(50秒) – 这实际上是整个事情需要的大致时间运行(由另一个计时器测量)。

编辑:

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

问题是它只看起来很容易(累积),因为ElapsedTime值总是只按递增顺序输出。

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

然后结果出现在初始顺序的输出中 – 总是按照任务持续时间的增加顺序:

以下是Console应用程序的输出:

 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(); 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) ); */ } } } 

最有可能发生的一件事是DoLongRunningTask()可能不是正确的multithreading,这意味着一个任务在第一个任务完成后运行,依此类推。 每个任务都有自己的计时器,它们都在大约同一时间开始(或者线程被分配给任务),但是长时间运行的任务会将它们全部抵消。

你永远不会有一个无限的线程池和任务处理谁获得一个线程和什么时候。

关于LongRunning:

“这不是一个特定的长度。如果你生成了很多任务,LongRunning就不适合他们。如果你生成一两个任务,相对于你的应用程序的生命周期会持续相当长的一段时间,然后LongRunning是需要考虑的事情。一般情况下,除非你发现你确实需要它,否则不要使用它。在幕后,它会导致使用更多的线程,因为它的目的是允许ThreadPool继续处理工作项,即使一个任务正在运行一段时间;如果该任务在池中的一个线程中运行,该线程将无法为其他任务提供服务。通常只使用LongRunning你通过性能测试发现,不使用它会导致其他工作处理的长时间延迟。“ – Stephen Toub

上述就是C#学习教程:任务中的秒表似乎是所有任务的附加,想要测量任务间隔分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/951951.html

(0)
上一篇 2021年11月19日
下一篇 2021年11月19日

精彩推荐