У меня есть ситуация, когда очень редко Очередь объектов убирает нуль. Единственный вызов Enqueue находится внутри самого класса:
m_DeltaQueue.Enqueue(this);
Очень редко нуль удаляется из этой очереди в следующем коде (статический метод):
while (m_DeltaQueue.Count > 0 && index++ < count)
if ((m = m_DeltaQueue.Dequeue()) != null)
m.ProcessDelta();
else if (nullcount++ < 10)
{
Core.InvokeBroadcastEvent(AccessLevel.GameMaster, "A Rougue null exception was caught, m_DeltaQueue.Dequeue of a null occurred. Please inform an developer.");
Console.WriteLine("m_DeltaQueue.Dequeue of a null occurred: m_DeltaQueue is not null. m_DeltaQueue.count:{0}", m_DeltaQueue.Count);
}
Это отчет об ошибке, который был сгенерирован:
[Январь 23 01:53:13]: m_DeltaQueue.Dequeue null произошло: m_DeltaQueue не равно нулю. m_DeltaQueue.count: 345
Я очень смущен тем, как нулевое значение может присутствовать в этой очереди.
Как я пишу это, мне интересно, может ли это быть неудачей синхронизации потоков? это многопоточное приложение, и возможно, что в очереди или в очереди может происходить одновременный вызов в другом потоке.
В настоящее время он находится под .Net 4.0, но ранее он был в версии 3.5/2.0
Update:
Это мое (надеюсь, правильное) решение проблемы, которое было ясно изложено, хотя большие ответы ниже были проблемой синхронизации.
private static object _lock = new object();
private static Queue<Mobile> m_DeltaQueue = new Queue<Mobile>();
Ставить:
lock (_lock)
m_DeltaQueue.Enqueue(this);
Dequeue:
int count = m_DeltaQueue.Count;
int index = 0;
if (m_DeltaQueue.Count > 0 && index < count)
lock (_lock)
while (m_DeltaQueue.Count > 0 && index++ < count)
m_DeltaQueue.Dequeue().ProcessDelta();
Я все еще пытаюсь получить правильную синхронизацию, поэтому любые комментарии относительно правильности этого будут очень оценены. Первоначально я решил использовать эту очередь как объект syncronization, потому что он частный, и вводит меньше беспорядка в то, что уже является очень большим классом. На основании предложения Джона я изменил это, чтобы заблокировать новый частный статический объект, _lock.