Я использую concurrentqueue, поэтому несколько пользователей могут записать свою информацию. На заднем плане я использую таймер, чтобы сэкономить все, что находится в очереди, в базу данных по времени. Мой код, как удар:Interlock compareexchange для коллекции
public void WriteInformation(sting msg)
{
ConcurrentQueue<MessageQueueItem> oldQueue;
do
{
oldQueue = messageQueue;
messageQueue.Enqueue(msg);
}
while (Interlocked.CompareExchange(ref oldQueue, null, messageQueue) != null);
}
В методе истечь мой таймер, я воссоздавая параллельную очередь и обработать старую очередь, как показано ниже:
var oldQueue = Volatile.Read(ref messageQueue);
Volatile.Write(ref messageQueue, new ConcurrentQueue<string>());
// process the old queue;
string item;
if (oldQueue.TryDequeue(out item))
{
// compact item and save to DB.
}
Является ли эта модель правильно? Также не думаю, что
var oldQueue = Volatile.Read(ref messageQueue);
Volatile.Write(ref messageQueue, new ConcurrentQueue<string>());
необходим. Я могу использовать код ниже, как в моем методе WriteInformation, я уже проверяю, является ли messageQueue актуальной копией. Правильно ли это? WriteInformation и messageQueue являются статическими. Благодарю.
var oldQueue = messageQueue;
messageQueue = new ConcurrentQueue<string>();
действие DB довольно медленно, поэтому я хочу создать новую очередь для людей, чтобы вводить данные, а поток таймера может обрабатывать старую очередь в фоновом режиме. – Helic
@Helic какая конкретная проблема решает вторая очередь? Почему вы не можете потреблять из той очереди, которая находится в очереди? – zerkms
@zerkms, я думаю, что слишком частые вызовы метода WriteInformation будут блокировать сбор слишком много раз и задерживать действие БД, и наоборот – Helic