2013-09-05 3 views
1

Я пытаюсь определить, является ли мой код, который я использую, Thread Thread или нет. Я в основном пытаюсь вызывать метод несколько раз из разных потоков и фиксировать время, необходимое для выполнения определенных вызовов внутри метода.Thread Safe Method with Stop Watch

Вот пример того, что я делаю.

using System; 
using System.Collections.Concurrent; 
using System.Diagnostics; 
using System.Linq; 
using System.Threading.Tasks; 

namespace ThreadTest 
{ 
class Program 
{ 
    static BlockingCollection<TimeSpan> Timer1 = new BlockingCollection<TimeSpan>(new ConcurrentBag<TimeSpan>()); 

    static TimeSpan CaptureTime(Action action) 
    { 
     Stopwatch stopwatch = Stopwatch.StartNew(); 
     action(); 
     stopwatch.Stop(); 
     return stopwatch.Elapsed; 
    } 

    static void ThreadFunction() 
    { 
     TimeSpan timer1 = new TimeSpan(); 
     timer1 = CaptureTime(() => 
      { 
       //Do Some Work 
      }); 
     Timer1.Add(timer1); 
    } 

    static void Main(string[] args) 
    { 
     for (int i = 0; i < 50; i++) 
     { 
      var task = new Task(ThreadFunction); 
      task.Start(); 
     } 
    } 
} 

}

И то, что я пытаюсь определить, может ли доверять значения TimeSpan, возвращаемые методом CaptureTime.

Спасибо всем, кто может просветить меня.

ответ

1

Их можно «доверять», но это не значит, что они будут очень точными.

Это зависит от множества факторов, но в основном вы хотели бы измерить большое количество звонков на action() (по этой же теме) и усреднить их. Особенно, если один вызов занимает относительно короткое время (< = 1 мс)

Вам все равно придется иметь дело с внешними факторами, Windows не является оперативной системой.

3

Использование Stopwatch здесь не проблема. См. Это recent answer. Поскольку вы используете один поток при использовании секундомера, он будет работать нормально.

Но я не уверен, что этот подход действительно будет очень полезен. Вы пытаетесь создать свой собственный профилировщик? Почему бы просто не использовать существующие инструменты для профилирования?

Когда вы вращаете 50 экземпляров одной и той же операции, они должны сражаться за одни и те же ресурсы ЦП. Кроме того, новый Task мог бы или не разворачивать новый поток. Даже тогда количество включенных переключений сделало бы результаты менее значимыми. Если вы специально не пытаетесь наблюдать параллельное поведение, я бы избегал такого подхода.

Лучше всего было бы, чтобы выполнить действие 50 раз последовательно, время все это, а затем разделить на 50. (Если предположить, что это короткое работает задача.)

использование BlockingCollection<TimeSpan>(new ConcurrentBag<TimeSpan>()) является также очень странно. Поскольку вы просто добавляете в список и статичны и предварительно созданы, вы можете просто использовать List<TimeSpan>. См. Примечания к Thread Saftey в документации List<T>here.

Игнорировать это. Я неправильно понял контекст документов. Ваш код в порядке, и он действительно потокобезопасен. Спасибо Джим и Алекси за это.

+0

Кроме того, вопросы такого характера лучше поставлены на [codereview.stackexchange.com] (http://codereview.stackexchange.com/) –

+0

+1. О предложениях по улучшению практики секундомера. Не согласен с 'List ' list-list не является потокобезопасным для добавления из нескольких потоков, поэтому его нельзя использовать в этом контексте. Также я бы не согласился, если этот вопрос лучше для codereview. Для меня это четко говорит о том, «если конкретный шаблон кодирования является потокобезопасным», без особого беспокойства, как написана остальная часть кода - SO считает нужным. –

+0

Если он использовал 'List ', ему нужно было бы заблокировать его, чтобы добавить к нему. –