ManualResetEvent и выпуск задачи - PullRequest
       9

ManualResetEvent и выпуск задачи

0 голосов
/ 14 февраля 2011

Я работал над настраиваемым многопоточным сервером, который использует HTTP для связи с клиентами.Для создания новых тем я использовал метод Task.Factory.StartNew ().Для синхронизации я использовал объекты ManualResetEvent.

Вот суть кода:

namespace ThreadTest {
    class Program {        
        private readonly ManualResetEvent _event = new ManualResetEvent(false);

        public void Start() {
            for (int i = 0; i < 100; i++) {
                int num = i;
                Task.Factory.StartNew(() => {
                    Console.WriteLine("Task {0} Started", num);
                    _event.WaitOne();
                });
            }  
        }      

        static void Main(string[] args) {
            var test = new Program();
            test.Start();
            Console.ReadLine();
        }
    }
}

В реальном коде объект _event в конечном итоге вызвал бы Setчтобы освободить ожидающие задачи.

Проблема, с которой я столкнулся, заключается в том, что этот код прекрасно работает на моей машине разработки (двухъядерной с двумя потоками на ядро ​​и использующей среду выполнения MS .NET 4).), но не работает на моем сервере (который является одноядерным с 1 потоком на ядро ​​и использует среду выполнения Mono 2.8).Вывод на моей машине разработки:

Task 0 Started
Task 1 Started
Task 3 Started
Task 2 Started
Task 4 Started
Task 5 Started
...

В то время как вывод сервера

Task 53 Started

Мой вопрос: что я неправильно понимаю в ManualResetEvent или Задачах?Почему TaskFactory продолжает выполнять задачи на двухъядерном, а не одноядерном?

Обновление:

Я только что попробовал это на моем двухъядерном (1 поток на ядро) ноутбук Mac, и я получил вывод

Task 97 Started
Task 1 Started

А потом ничего.Я также попробовал его с Mono на моей машине для разработки (4 потока) и получил:

Task 99 Started
Task 2 Started
Task 98 Started
Task 0 Started

Так что это похоже на ошибку с Mono.

Ответы [ 2 ]

2 голосов
/ 27 апреля 2011

Оказывается, это была ошибка в Mono.Я подал отчет , и теперь он исправлен.

0 голосов
/ 14 февраля 2011

Ваш код в том виде, в котором он представлен, никогда не выполнит ни одну из задач, так как событие никогда не сигнализируется.В конечном итоге у него заканчиваются потоки для распределения, и он блокируется.На самом деле проблема заключается в том, «сколько потоков запускает параллельная библиотека задач при разных конфигурациях ЦП, когда ни один из потоков не может продолжить работу», поскольку именно это эффективно измеряет ваш код.ThreadPool, который использует алгоритм набора высоты, чтобы приспособиться к числу потоков, чтобы максимизировать скорость выполнения рабочего элемента.Алгоритм учитывает, сколько у вас ядер.

Существуют лучшие способы использовать параллельную библиотеку задач для планирования работы, выполняемой после завершения задачи, способами, которые не связывают потоки, например ContinueWith.Чего вы пытаетесь достичь с помощью конструкции события?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...