【问题标题】:Log the time taken by a Thread记录线程花费的时间
【发布时间】:2014-02-20 21:53:23
【问题描述】:

我有这段代码生成 6 个线程并在每个线程上同时执行 GetAverage 方法。

 var threadFinishEvents = new List<EventWaitHandle>();
 //StopWatch sw = new StopWatch();
 for (int i = 0; i < 6; i++)
 {
      var threadFinish = new EventWaitHandle(false, EventResetMode.ManualReset);
      threadFinishEvents.Add(threadFinish);
      var thread = new Thread(delegate()
                            {
                                GetAverage(userName);
                                threadFinish.Set();
                                //sw.Stop();
                            });
              //sw.Start();
              thread.Start();
 }
 Mutex.WaitAll(threadFinishEvents.ToArray(), threadTimeout);
 long timeElapsed = sw.TimeElapsed();

我想记录每个线程执行的时间并将其记录到数据库中。我在谷歌上阅读了很多建议使用Stopwatch 的帖子。我尝试将Stopwatch 代码(我已注释掉)添加到 sn-p 但不确定这是否正确。有人可以帮帮我吗?

【问题讨论】:

    标签: c# .net multithreading stopwatch


    【解决方案1】:

    如果您想要总时间,请在循环之前启动秒表并在WaitAll 之后停止。

    如果您需要对每个线程进行单独测量,请为循环内的每个线程创建单独的秒表。将sw.Start() 放在委托的开头,将sw.Stop() 放在委托的末尾。将秒表放在一个列表中(就像使用 EventWaitHandle 一样)并读取代码末尾的 TimeElapsed 值。

    【讨论】:

    • 我应该在代码中的哪个位置进行更改?你能帮我解决一下吗?
    • @user1550951:当然。我的回答中哪一部分不清楚?
    • 将 sw.Start() 放在委托的开头,将 sw.Stop() 放在委托的末尾。将秒表放在一个列表中(就像使用 EventWaitHandle 一样)并在代码末尾读取 TimeElapsed 值。这是否意味着我必须将 sw.Start() 作为“GetAverage”中的第一行"方法?
    • @user1550951:我会将 sw.Start() 放在 delegate() {GetAverage() 之间,然后将 sw.Stop() 放在 GetAverage 之后。
    【解决方案2】:

    有 2 种可能性来测量 平均时间:测量总时间并将其除以线程数或测量每个线程时间,将其相加并除以数字(但在这种情况下,您可以称为移动平均,在获得最后一个线程时间之前可用)。使用哪一个 - 取决于。

    测量总时间

    var watch = new StopWatch();
    watch.Start();
    // .. whole job, creating N threads, waiting for all of them to finish
    watch.Stop();
    var result = watch.Elapsed / N;
    

    它将包括开销(循环时间、创建线程、执行第一个线程等),但运行的线程越多,它就会越准确。

    测量每个线程的时间

    //  inside each thread
    var watch = new StopWatch();
    watch.Start();
    // ... thread job
    watch.Stop();
    timeX = watch.Elapsed;
    
    // after job is done
    Mutex.Wait...
    result = (time1 + time2 + ... ) / N;
    

    您不包括任何开销,最准确的结果。但是你必须保留所有timeX

    移动平均时间

    //  inside each thread
    var watch = new StopWatch();
    watch.Start();
    // ... thread job
    watch.Stop();
    result = (_timePrevious + watch.Elapsed) / 2;
    _timePrevious = watch.Elapsed;
    
    // after job done
    result = result; // total result is the same as the most recent
    

    这里我们只使用了 2 个测量值(result 的第一个值将不准确,因为 _timePrevious 未初始化),但可能更多。您可以有一个动态列表来保存 所有 次(这使得结果在最后最准确),或者,例如,具有移动位置的固定数组(第一次测量填充,但随后更新通过新线程)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-24
      • 1970-01-01
      • 2014-04-23
      • 1970-01-01
      • 2021-09-22
      • 2012-11-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多