При именовании потока внутри Parallel.Invoke возникает исключение "Это свойство уже установлено и не может быть изменено".
У меня есть приложение, которое долгое время работало без проблем, которое внезапно не запускается из-за следующей ошибки:
Msgstr "Это свойство уже установлено и не может быть изменено."
Когда я проверяю код, который в основном напоминает приведенный ниже фрагмент, я вижу, что исключение выдается в строке, которая пытается назвать первую задачу внутри Parallel.Invoke.
Thread.CurrentThread.Name = "Main Program Thread";
// Do some start up tasks in parallel
Parallel.Invoke(new ParallelOptions { MaxDegreeOfParallelism = 10 },
() =>
{
Thread.CurrentThread.Name = "First thread";
},
() =>
{
Thread.CurrentThread.Name = "Second thread";
});
...
Очевидно, причиной этого должно быть то, что у основного потока уже есть имя, и первая задача выполняется в основном потоке, а не в потоке потоков.
Хотя я могу решить эту проблему, не называя нити внутри Parallel.Invoke, мне любопытно, почему это внезапно начало происходить. Является ли это случаем, что обычно Parallel.Invoke() ранее выполнял все свои задачи в потоках пула потоков и по какой-то причине больше не может этого делать? Что может вызвать такие вещи?
Чем больше я смотрю на этот код, тем больше я озадачен тем, что он когда-либо работал. Мне кажется, этот код всегда должен вызывать исключение.
3 ответа
Parallel
обычно выполняет некоторую работу в пуле потоков, а другую в текущем потоке, чтобы не дать ему бездействовать. Это не гарантируется, вся работа может выполняться в пуле или в текущем потоке.
Я не знаю, что происходит, когда вы назначаете имя потоку пула. Либо он бросает, ничего не делает или работает один раз. Ничего из этого не желательно.
Выбросьте этот код. Не связывайтесь с темами, которые вам не принадлежат.
Вы можете использовать LongRunning
опция задачи, чтобы получить выделенные потоки, которые вы можете настроить.
Потоки потоков пула используются повторно. Поток, в котором выполняется задача пула потоков , не принадлежит вам. То, что вы делаете, явно запрещено, так что не удивляйтесь, если оно взорвется вам в лицо.
Помимо этого, Parallel.Invoke
находится в пределах своих разумных рабочих параметров, когда запускает часть своего кода в том же потоке, из которого он вызван - нет смысла просто ждать завершения всех остальных потоков и тратить идеальный поток.
Я удалил.NET 4.6, и этот код снова начал работать. Должна быть оптимизация в Parallel.Invoke в более новых версиях фреймворка, которая выявила ошибку в нашем коде там, где она никогда раньше не проявлялась.