我试图阻止一些线程,阅读一些关于正确地做到这一点的正确方法的事情,但我必须做错什么,因为它根本不起作用。起初我尝试没有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()
仍然是正确的。
答案 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%确定这是问题所在。但至少它应该有助于清理一些事情。