我有一个使用Task
(TPL)对象进行异步执行的应用程序。
主线程等待触发器(某些TCP数据包),然后执行多个任务。我想要做的是衡量在任务中花费的时间。
看看代码。我有一些冗长的操作(Generator
),包含在Stopwatch's
开始/停止。
Task.Factory.StartNew((t) => {
Stopwatch sw = new Stopwatch();
sw.Start();
Generator g = new Generator();
g.GenerateIntervals(); // lengthy operation
sw.Stop();
GlobalStopwatch.Add(sw.Elapsed);
});
这是问题所在。秒表在DateTime.UtcNow.Ticks
时使用Start()
,然后在Stop()
时刻再次使用Generator
。然后它减去这两个以获得经过的时间。
问题是,一些其他线程(在单线程系统中)可以获得一些处理器时间,而GenerateIntervals()
(来自代码)正在执行其Generaor.GenerateIntervals()
冗长的操作。这意味着秒表记录的经过时间不仅包含{{1}}时间,还包含其他线程在其间工作的时间。
有没有简单的方法可以确切地知道某些方法花费了多少处理器时间,而不包括由于分时机制而导致其他线程的执行时间?
答案 0 :(得分:4)
您的问题的答案是“否”......不,您无法衡量特定thread
的在CPU 上的累积时间。
(旁边咆哮:我真的希望人们在回答之前阅读问题并理解它!)
好的,回到你的问题......你能做的最准确的事情就是为每个任务分离一个单独的process
,然后测量进程的CPU时间(可以是在.Net完成......)但这太过分了。
如果您需要有关如何操作的帮助,您应该专门提出另一个问题。
答案 1 :(得分:1)
Here很好。您可以使用它,或者您可以使用VS2010中的内置性能分析器来比较这些时间。
答案 2 :(得分:0)
您可以使用Windows API QueryPerformanceCounter()和 QueryPerformanceFrequency()方法来检索自计时器启动以来经过的毫秒数。
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Threading;
namespace Win32
{
internal class WinTimer
{
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter(
out long lpPerformanceCount);
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(
out long lpFrequency);
private long startTime, stopTime;
private long freq;
// Constructor
public HiPerfTimer()
{
startTime = 0;
stopTime = 0;
if (QueryPerformanceFrequency(out freq) == false)
{
// high-performance counter not supported
throw new Win32Exception();
}
}
// Start the timer
public void Start()
{
// lets do the waiting threads there work
Thread.Sleep(0);
QueryPerformanceCounter(out startTime);
}
// Stop the timer
public void Stop()
{
QueryPerformanceCounter(out stopTime);
}
// Returns the duration of the timer (in seconds)
public double Duration
{
get
{
return (double)(stopTime - startTime) / (double) freq;
}
}
}
}
答案 3 :(得分:0)