Подтвердить что ты не робот

Лучший потокобезопасный способ увеличения целого числа до 65535

У меня есть System.Timers.Timer, который увеличивает счетчик каждые 3 секунды. Другой поток также может установить эту переменную в любое значение при некоторых условиях.

Пытался использовать Interlocked.Increment, но у него нет перегрузки для UInt16. Следующее, что нужно сделать, это блокировка, но я не уверен, как сделать потокобезопасный доступ (чтение/запись/приращение) к этой переменной.

Отредактировано: в исходном коде использовался int, но он был изменен на UInt16, как предполагалось

private volatile System.UInt16 mCounter = 0;
private readonly object mCounterLock = new object();
public System.UInt16 Counter {
  get {
    lock (mCounterLock) {
      return mCounter;
    }
  }
  set {
    lock (mCounterLock) {
      mCounter = value;
    }
  }
}
private System.Timers.Timer mCounterTimer;

void mCounter_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
  lock (mCounterLock) {
    Counter++;
  }
}
4b9b3361

Ответ 1

Просто измените значение Int32 на Int16, если вам нужно всего 2 байта. Поскольку Шай удалил свой ответ здесь, код

UInt16 myval = 0;
Object myvalLock = new Object();
....
lock (myvalLock) { myval++; }

Ответ 2

Используйте комбинацию Interlocked.CompareExchange и Interlocked.Increment, в которой вы назначаете 0, если значение достигает 65535

Ответ 3

Я бы просто использовал UInt32 с Interlocked.Increment и передал его UInt16 после каждого доступа для чтения.

Ответ 4

volatile int iNum = 0;
...


iActual = iNum;
do
{
   iExpected = iActual;
   iNext = (iExpected+1) & 0xFFFF;
   iActual = Interlocked.CompareExchange (ref iNum, iNext, iExpected);
} while (iExpected != iActual);
return iNext;

Это делает поток инкремента безопасным против других приращений. Но вы также упоминаете также "читать", "писать" и "reset", и невозможно сказать, в контексте, если эти операции безопасны и даже если приращение является дефисом против "write" и специально "reset 'операций. Обычно для такого типа общих счетчиков разрешена операция только, чтобы увеличить ее.