スレッドが古いコピーを参照している可能性があることを覚えておく必要があります。ロックすることで、参照している変数のバージョンが更新されていることを確認できます。
私が最初にコーディングを開始し、変数の最新のコピーは必要ないのではないかと考えたとき、変数は最終的に更新されると想定しているため、無限ループに陥りましたが、変数がキャッシュされている場合は更新されません。
簡単な説明付きの例を含めました。スレッドの開始方法は気にしないでください。関連性はありません
private static bool _continueLoop = true;
private static readonly object _continueLoopLock = new object();
private static void StopLoop()
{
lock(_continueLoopLock)
_continueLoop = false;
}
private static void ThreadALoopWillGetStales()
{
while(_continueLoop)
{
//do stuff
//this is not guaranteed to end
}
}
private static void ThreadALoopEventuallyCorrect()
{
while(true)
{
bool doContinue;
lock(_continueLoopLock)
doContinue = _continueLoop;
if(!doContinue)
break;
//do stuff
//this will sometimes result in a stale value
//but will eventually be correct
}
}
private static void ThreadALoopAlwaysCorrect()
{
while(true)
{
bool doContinue;
lock(_continueLoopLock)
if(!_continueLoop)
break;
//do stuff
//this will always be correct
}
}
private static void ThreadALoopPossibleDeadlocked()
{
lock(_continueLoopLock)
while(_continueLoop)
{
//if you only modify "_continueLoop"
//after Acquiring "_continueLoopLock"
//this will cause a deadlock
}
}
private static void StartThreadALoop()
{
ThreadPool.QueueUserWorkItem ((o)=>{ThreadALoopWillGetStales();});
}
private static void StartEndTheLoop()
{
ThreadPool.QueueUserWorkItem((o)=>
{
//do stuff
StopLoop();
});
}
public static void Main(string[] args)
{
StartThreadALoop();
StartEndTheLoop();
}
ループを開始すると、変数の古いコピーを取得し続ける可能性があります。そのため、複数のスレッドにまたがってアクセスするときに何らかの同期が必要です。