如何在给定点停止线程?

时间:2009-03-29 15:28:45

标签: c# multithreading

我试图阻止一些线程,阅读一些关于正确地做到这一点的正确方法的事情,但我必须做错什么,因为它根本不起作用。起初我尝试没有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()设置了一个断点,即使我传入了_IsRunnigStop()仍然是正确的。

2 个答案:

答案 0 :(得分:5)

由于你的start方法的编写方式,这里需要锁定,但是,你只需要Start()(现在不是)和Stop()的锁定,因为它们是唯一可能导致你的情况发生竞争的人。

我会完全从您的SendLoop()方法移除锁定(因为Stop等待锁定设置_isRunning而导致DeadLock SendLoop持有锁直到_isRunning设置为false)。现在,当您致电Stop()时,锁定会阻止它设置_isRunning = false;

但是,您需要使用Start()Stop()方法进行锁定(除非您按照完全构造的方式进行返工)。类似的东西:

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个线程,并且还会在线程启动之前阻止Stop停止。

答案 1 :(得分:2)

你需要稍微重新组织你的循环。现在你在runLock上持有很长一段时间的锁定。这将导致任何调用Stop方法的人挂起,直到if块成功或Sleep调用返回。这可能会导致问题,因为在调用Stop方法时,只有在返回时才能查看_isRunning。尝试重新组织您的代码,如下所示

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

我不是100%确定这是问题所在。但至少它应该有助于清理一些事情。