2009-03-29 4 views
4

私はいくつかのスレッドを止めようとしていましたが、正常に行うための正しい方法についていくつかのことを読んでいましたが、単純にうまくいかないので何か間違っている必要があります。最初は、lock()なしで、_IsRunningが揮発性であり、ロックで試してみました。ここに私が持っているものがあります。与えられた時点でスレッドを停止する方法は?

private volatile bool _IsRunning; 
private static readonly object runLock = new object(); 

public void Start() 
{ 
    if (_IsRunning == true) 
     return; 
    _IsRunning = true; 
    (new System.Threading.Thread(new System.Threading.ThreadStart(SendLoop))).Start(); 
} 

public void Stop() 
{ 
    lock (runLock) 
    { 
     _IsRunning = false; 
    } 
} 

private void SendLoop() 
{ 
    while (_IsRunning) 
    { 
     lock (runLock) 
     { 
      if (_sockets.Count > 0) 
      { 
       //some stuff 
      } 
      else 
      { 
       System.Threading.Thread.Sleep(10); 
      } 
     } 
    } 
} 

私はwhile()にブレークポイントを設定し、_IsRunnigは私がStop()に渡されていてもまだ本当です。

答えて

5

ここでは、起動方法の書き方によってロックが必要ですが、Start()(ここは現在ではありません)とStop()のロックが必要ですあなたの場合の競争状態。

私は(それが_isRunningを設定するために、ロックを待っている状態、および_isRunningがfalseに設定されるまで、あなたのSendLoopがロックを保持しているStopので、DeadLockを引き起こして)完全にあなたのSendLoop()方法からロックを削除します。あなたがStop()を呼び出すときに今、ロックは(あなたは彼らが完全に構成されている方法を手直ししない限り)しかし、あなたはあなたのStart()Stop()方法でロックが必要になり、これまで_isRunning = false;

を設定するから、それを妨げています。次のようなものがあります。

public void Start() 
{ 
    lock (runLock) 
    { 
     if (_IsRunning == true) 
      return; 
     _IsRunning = true; 
     (new System.Threading.Thread(new System.Threading.ThreadStart(SendLoop))).Start(); 
    } 
} 

public void Stop() 
{ 
    lock (runLock) 
    { 
     _IsRunning = false; 
    } 
} 

これは、2つのスレッドの開始を防ぎ、スレッドの開始前に停止を停止します。

+0

ありがとうございます!あなたのアンサーは私に本当のデッドロックの問題を認識させました!私の解決策では、ループ中にロックする必要がありますが、スリープは絶対に避けなければなりません! – Tipx

2

ループを少し再編成する必要があります。今は非常に長い時間runLockにロックを保持しています。これにより、ifブロックが成功するか、Sleep呼び出しが返るまで、Stopメソッドを呼び出すすべての人がハングします。これは、Stopメソッドが呼び出されたときに_isRunningを返すときだけ見ることができないため、問題につながります。

private void SendLoop() { 
    do { 
    if (_sockets.Count > 0) { 
    } else { 
     System.Threading.Thread.Sleep(10); 
    } 
    bool shouldContinue; 
    lock (runLock) { 
     shouldContinue = _IsRunning; 
    } 
    while(shouldContinue); 
} 

これは問題ではないかと私は確信していません。しかし、少なくともそれは少し物事を明確にするのに役立つはずです。

関連する問題