При именовании потока внутри 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 в более новых версиях фреймворка, которая выявила ошибку в нашем коде там, где она никогда раньше не проявлялась.

Другие вопросы по тегам