Моя самая большая ненавистная особенность - любой синтаксис файла конфигурации, который включает условную логику. Подобные вещи распространены в мире Java (муравей, мавен и т. Д. Вы знаете, кто вы есть!).
Вы просто заканчиваете программирование на языке c ** p с ограниченной отладкой и ограниченной поддержкой редактора.
Если вам нужна логика в вашей конфигурации, «Pythonic» подход кодирования конфигурации на реальном языке будет намного лучше.
Вы можете чтобы изменить значение элемента в коллекции. Ошибка, которую вы получаете, означает, что элемент был либо добавлен, либо удален, то есть: была изменена сама коллекция, а не элемент внутри коллекции. Скорее всего, это вызвано тем, что другой поток добавляет или удаляет элементы из этой коллекции.
Вы должны заблокировать свою очередь в начале вашего метода, чтобы другие потоки не изменяли коллекцию, пока вы обращаетесь к ней. Или вы можете заблокировать коллекцию еще до вызова этого метода.
private bool extractWriteActions(out List<WriteChannel> channelWrites)
{
lock(tpotActionQueue)
{
channelWrites = new List<WriteChannel>();
foreach (TpotAction action in tpotActionQueue)
{
if (action is WriteChannel)
{
channelWrites.Add((WriteChannel)action);
action.Status = RecordStatus.Batched;
}
}
}
return (channelWrites.Count > 0);
}
Я думаю, что у меня было аналогичное исключение при использовании цикла foreach
в коллекции, где я пытался удалить элементы из Коллекции (а может, это был Список, не помню). В итоге я решил обойти это, используя цикл for
. Возможно, попробуйте что-нибудь вроде следующего:
for (int i=0; i<tpotActionQueue.Count(); i++)
{
TpotAction action = tpotActionQueue.Dequeue();
if (action is WriteChannel)
{
channelWrites.Add((WriteChannel)action);
lock(tpotActionQueue)
{
action.Status = RecordStatus.Batched;
}
}
}
Я думаю, все, что вам нужно сделать, это перестать использовать foreach и вместо этого переключить его на цикл for
for(int i = 0; i < tpotActionQueue.Length; i++)
{
TpotAction action = tpotActionQueue[i];
if (action is WriteChannel)
{
channelWrites.Add((WriteChannel)action);
lock(tpotActionQueue)
{
action.Status = RecordStatus.Batched;
}
}
}
С уважением, Майк.
У вас нет определения для tpotActionQueue
, но если это обычный List
, то эта строка не ваша проблема. Изменение коллекции - это добавление или удаление элементов, а не установка свойства для содержащегося объекта.
У вас есть блокировка (tpotActionQueue)
и тег безопасности потоков, поэтому я предполагаю, что есть еще один поток, добавляющий или удаление элементов из tpotActionQueue
во время перечисления. Вероятно, вам потребуется синхронизировать эти доступы.
Как насчет некоторых возможностей LINQy?
private bool extractWriteActions(out List<WriteChannel> channelWrites)
{
channelWrites= tpotActionQueue.Where<WriteChannel>(x => x is WriteChannel).ToList()
foreach(WriteChannel channel in channelWrites) {
channel.Status = RecordStatus.Batched;
}
return ( channelWrites.Count > 0);
}
Я думаю, у вас должен быть другой поток, изменяющий tpotActionQueue, пока вы повторяете его. Поскольку вы блокируете эту очередь только внутри цикла for, это возможно.