Давайте возьмем образец класса SomeThread, где мы пытаемся запретить методы DoSomething после того, как свойство Running установлено в false, и Dispose вызывается классом OtherThread, потому что, если они вызывается после метода Dispose, это мир конец, как мы его знаем.
Похоже, есть шанс, что что-то зло произойдет из-за цикла. В тот момент, когда он запускает следующий цикл и до того, как блокировка будет предпринята перед вызовом методов DoSomething, Running может быть изменен на false, а Disposed вызывается до того, как он ударит блокировку. В этом случае жизнь не будет хорошей.
Я искал способы справиться с этим при использовании цикла в простом методе поддержки. Для записи я рассмотрел шаблон Double Lock Check, но, похоже, он не рекомендуется для С#.
Предупреждение:. Это упрощенный пример, чтобы попытаться сосредоточиться на проблеме с циклом и блокировкой в одном. Если я не уточню достаточно места, пожалуйста, дайте мне знать, и я сделаю все возможное, чтобы заполнить любые детали.
public class SomeThread : IDisposable
{
private object locker = new object();
private bool running = false;
public bool Running
{
get
{
lock(locker)
{
return running;
}
}
set
{
lock(locker)
{
running = value;
}
}
}
public void Run()
{
while (Running)
{
lock(locker)
{
DoSomething1();
DoSomething2();
}
}
}
private void DoSomething1()
{
// something awesome happens here
}
private void DoSomething2()
{
// something more awesome happens here
}
public void Dispose()
{
lock (locker)
{
Dispose1();
Dispose2();
}
}
private void Dispose1()
{
// something awesome happens here
}
private void Dispose2()
{
// something more awesome happens here
}
}
public class OtherThread
{
SomeThread st = new SomeThread();
public void OnQuit()
{
st.Running = false;
st.Dispose();
Exit();
}
}