У меня есть две функции A и B, а также условие, позволяющее решить, какую функцию выполнять.A сам по себе является потокобезопасным, несколько вызовов A могут выполняться одновременно, B нет и синхронизируется. Но во время выполнения B условие может измениться (с false на true), и поэтому все потоки, выполняющие A в это время, будут выдавать ошибки.
Код: Выделить всё
if (condition)
{
A();
}
else
{
B();
}
A - thread safe
B - Synchronized using [MethodImpl(MethodImplOptions.Synchronized)]
Пожалуйста, предложите способ добиться этого.
Некоторые уточнения:
Я создаю кеш, и производительность очень важна, поэтому полная блокировка невозможна.
Условием является наличие или отсутствие запрошенных данных. в кеше.
A() = AddToUpdates() — выполняется при попадании в кэш, просто добавляет количество обновлений для определенного ключа кэша, используя параллельный словарь.
B() = ProccessUpdates() и EvictLeastPriorityEntry() - При выполнении при промахе в кэше все предыдущие обновления будут обработаны, а базовая структура данных, хранящая порядок записей в кэше, будет переупорядочена.
И тогда запись с наименьшим приоритетом будет изменена. удалено.
Как уже упоминалось в принятом ответе, ReaderWriterLock, кажется, лучший вариант.
Однако есть только одна проблема:
Скажем, , поток 1 начинает выполнение, и происходит попадание в кэш (для записи с наименьшим приоритетом), что означает, что условие if истинно и входит в блок if. Но перед вызовом A() управление переключается на поток2.
thread2 - происходит промах кэша, выполняется переупорядочение и вытеснение (Запись, к которой A() из потока1 необходим доступ). p>
Теперь, когда управление возвращается в поток 1, произойдет ошибка.
Это решение, которое, по моему мнению, должно сработать:
Код: Выделить всё
_lock.EnterReadLock();
if (condition)
{
A();
}
_lock.ExitReadLock();
if (!condition)
{
B();
}
void A()
{
// ....
}
void B()
{
_lock.EnterWriteLock();
// ...
_lock.ExitWriteLock();
}
Спасибо.
Подробнее здесь: https://stackoverflow.com/questions/729 ... in-c-sharp
Мобильная версия