, если вы хотите easy код и не беспокоиться о производительности слишком много, это может быть так просто, как
class Foo
{
bool doingWork;
object m_lock=new object();
void DoWork()
{
lock(m_lock) // <- not sophistocated multithread protection
{
if (doingWork)
return;
doingWork = true;
}
try
{
[do work here]
}
finally
{
lock(m_lock) //<- not sophistocated multithread protection
{
doingWork = false;
}
}
}
}
Если вы хотите инкапсулировать блокировкунемного вы можете создать свойство, которое является поточно-ориентированным, как это:
public bool DoingWork
{
get{ lock(m_Lock){ return doingWork;}}
set{lock(m_lock){doingWork=value;}}
}
Теперь вы можете использовать его вместо поля, однако это приведет к увеличению времени, затрачиваемого на блокировку, так как увеличивается число блокировок.
Или вы можете использовать подход с полным забором (из большой книги по потокам Джозеф Альбахари, онлайн-потоки )
class Foo
{
int _answer;
bool _complete;
void A()
{
_answer = 123;
Thread.MemoryBarrier(); // Barrier 1
_complete = true;
Thread.MemoryBarrier(); // Barrier 2
}
void B()
{
Thread.MemoryBarrier(); // Barrier 3
if (_complete)
{
Thread.MemoryBarrier(); // Barrier 4
Console.WriteLine (_answer);
}
}
}
Он утверждает, что полный забор в 2 раза быстрее, чем оператор блокировки.В некоторых случаях вы можете улучшить производительность, удалив ненужные вызовы MemoryBarrier (), но использование lock
просто, более понятно и менее подвержено ошибкам.
Я полагаю, что это также можно сделать с помощью класса Interlocked
, основанного на поле intWorking на основе int.