2010-07-30 6 views
2

메시지 전송 횟수를 제한하기 위해 스로틀을 설정하는 중입니다. 이 방법이 효과가 있긴하지만, 더 좋은 방법이 있다면 호기심이 있습니까? 모든 조언을 부탁드립니다.코드 검토 (멀티 스레딩시 첫 번째 시도)

public Class MyApp 
{ 
    private long _messagesSent; 
    private long _totalMessagesSent; 

    public int NumberOfMessages { get; set; } 
    public int MessagesPerSecond { get; set; } 

    public void SendMessage() 
    { 
     ThreadholdMonitor.Start(); 

     for (var i = 0; i < NumberOfMessages; i++) { 
      // Code here... 

     if (MessagesPerSecond <= _messagesSent) { 
      ThreadholdMonitor.StopSendingEvent.Set(); 

      lock (this) { 
       var hasPrinted = false; 
       while (ThreadholdMonitor.StopSendingEvent.WaitOne(0, false)) { 
        if (hasPrinted == false) { 
         Console.WriteLine("Sent " + _messagesSent + " messages"); 
         hasPrinted = true; 
        } 

        Interlocked.Exchange(ref _messagesSent, 0); 
       } 
      } 
     } 

     SendMessage(details); 
     Interlocked.Increment(ref _messagesSent); 
     Interlocked.Increment(ref _totalMessagesSent); 

     } 

     ThreadholdMonitor.Stop(); 
    } 
} 

public class ThreadholdMonitor 
{ 
    private static ManualResetEvent _monitorEvent; 

    public static ManualResetEvent StopSendingEvent { get; set; } 

    public static void Start() 
    { 
     _monitorEvent = new ManualResetEvent(false); 
     StopSendingEvent = new ManualResetEvent(false); 

     Thread monitorThread = new Thread(new ThreadStart(ControlSharedSignal)); 
     monitorThread.Start(); 
    } 

    public static void Stop() 
    { 
     _monitorEvent.Set(); 
    } 

    private static void ControlSharedSignal() 
    { 
     var startTime = DateTime.Now; 

     while (_monitorEvent.WaitOne(0, false) == false) { 
      if (DateTime.Now.Subtract(startTime).Seconds >= 1) { 
       StopSendingEvent.Reset(); 
       startTime = DateTime.Now; 
      } 
     } 
    } 
} 
+1

코드가 너무 많고 주석이 충분하지 않습니다. 이 코드가 무엇을하려하는지 설명하십시오. –

+1

말도 안돼, 당신은 코멘트가 필요하지 않습니다. 하지만 코드를 읽지 않고 이해할 수 있으면 코드를 읽고 이해할 수 있어야합니다. 어쨌든 당신이 가져야 할 것입니다. –

+0

읽을 수 없다면 사과드립니다. 첫 번째 시도였습니다. :( – Ryan

답변

1

세마포어를 사용하십시오. 가장 좋은 방법은 세마포어를 사용하는 것입니다. 그러면 스로틀과 자동 대기가 동시에 제공됩니다.

3

하지 마십시오. 보기 좋지 않습니다. 하지만 무엇보다도 나중에 발생할 수있는 문제가이 코드로 인해 발생하지 않았는지 결코 확신 할 수 없습니다. 조만간 실행하게 될 필연적 인 스레딩 레이스를 진단하기 위해 얻을 수있는 모든 도움이 필요합니다. 진짜로 진절머리 같은 종류의 버그들입니다. 문제를 디버그하려고 할 때 잠시 동안 한 번만 치는 것이고, 하지 마십시오. repro. 이러한 문제의 원인이 될 수있는 코드가 적을수록 좋습니다.

이 태그가 C# 4.0으로 태그 지정된 경우 .NET 4.0 프레임 워크는 System.Collections.Concurrent 네임 스페이스에서 우수한 클래스를 갖습니다. BlockingCollection 클래스는 사용자가하려는 일을하기 위해 만들어졌습니다. 스레딩 경주에 결코 노출되지 않도록 검증되고 끊임없이 테스트 된 것은 아니며 하드 스레딩 문제로 고생하지 않도록 설계되었습니다. 교착 상태, 기아, 우선 순위 반전, 자물쇠 호랑이처럼. 네가 머리를 잃어 버리는 그런 종류의 쓰레기.

면책 조항 : 나는 머리카락을 많이 남기지 않았습니다.

+0

나는 그것이 여기에 왜 게시 좋은지 알지 못했다. 알고 제안 해 주셔서 정말 고마워요. 스레딩에 정말 새롭습니다. blockingCollection 클래스에 익숙하지 않아서 고맙습니다. 감사합니다. – Ryan