Так требования:
- несколько потоков чтения одного
bool
переменной
- если нить видит значение
false
это должно изменить его true
и выполнить дополнительную работу
- если нить видит значение
true
, то ничего не должно произойти
- только один поток должен быть BLE, чтобы изменить значение и выполнить дополнительную работу
Так что код будет выглядеть следующим образом:
public class Example
{
private bool b = false;
public void DoSomething()
{
if (!b)
{
b = true;
DoExtraStuff();
}
}
}
Это, конечно, не является безопасным, если есть несколько потоков, исполняющих DoSomething
и намерение состоит в том, что DoExtraStuff
должен выполняться только один раз. Проблема в том, что потоки будут гоняться за чтением и записью b
.
Вам действительно нужно сделать чтение и запись в b
атомарным. Это можно сделать, используя ключевое слово lock
.
public class Example
{
private bool b = false;
private object locker = new object();
public void DoSomething()
{
bool trigger = false;
lock (locker)
{
if (!b)
{
b = true;
trigger = true;
}
}
if (trigger)
{
DoExtraStuff();
}
}
}
Существует альтернативный шаблон с использованием CAS операции с помощью Interlocked.CompareExhange
. К сожалению, нет перегрузки, которая принимает bool
, но если вы хотите изменить это bool
на int
, то также будет работать следующее.
public class Example
{
private int b = 0;
public void DoSomething()
{
if (Interlocked.CompareExchange(ref b, 0, 1) == 0)
{
DoExtraStuff();
}
}
}
На каком языке это? – Tudor