Вот правильное решение с помощью пониманий списка (они являются обратными в вопросе):
>>> join = lambda it: (y for x in it for y in x)
>>> list(join([[1,2],[3,4,5],[]]))
[1, 2, 3, 4, 5]
В Вашем случае это было бы
[image for menuitem in list_of_menuitems for image in menuitem.image_set.all()]
, или Вы могли использовать join
и сказать
join(menuitem.image_set.all() for menuitem in list_of_menuitems)
В любом случае, глюк был вложением эти for
циклы.
Совершенно верно. System.AggregateException добавлен в .NET 4 специально для этой цели во время параллельных операций.
Да, это законно. Исключения - это (вообще говоря) описательные объекты без привязки к потокам.
Лучше заключить исключение потока в новое исключение:
throw new Exception("Something descriptive here", localEx);
Таким образом, трассировка стека в localEx будет сохранена (как InnerException
нового исключения).
То, что вы делаете, не является перебросом. Это новый выброс экземпляра исключения, который у вас был в переменной. Даже если бы вы использовали только один поток, это было бы плохой идеей, поскольку из-за этого исключение выглядит так, как будто оно пришло с сайта throw. Я понятия не имею, как кто-то узнает об изменении потока при использовании нескольких потоков.
Я не понимаю, почему это не сработает, но вы должны помнить, что вы на самом деле не генерируете исключение повторно. Вы генерируете новое исключение, это просто тот же объект исключения. Так, например, трассировка стека скажет, что она была выбрана из "throw localEx;" вместо того, откуда исходит исходное исключение.
Это допустимо и не является повторным вызовом, это новое исключение, выброшенное в другом потоке (с тем же объектом исключения)
Я не знаю, почему вы считаете это незаконным. Если бы это было незаконно, компилятор наверняка перехватил бы это, или среда выполнения выдала бы исключение. Собственно говоря, я использую этот паттерн. @John В приложении Windows Forms, которое вызывает веб-службы с использованием фонового потока, я использую этот способ. Затем исключение обрабатывается в обработчике верхнего уровня Application.ThreadException, регистрируется и т. Д. Нет необходимости знать, в каком потоке возникло исключение.