создание и завершение потока, содержащегося в коллекции - PullRequest
0 голосов
/ 20 октября 2011

У меня есть пользовательская коллекция (потокобезопасная ObservableQueue).Я реализовал бизнес-логику внутри класса коллекции (т.е. удалял элементы по очереди и выставлял их снаружи).Это работает нормально.Чтобы коллекция не блокировала поток, в котором она инициализирована, OnservableQueue реализует поток для выполнения этой работы.Теперь я не совсем уверен в возможных подводных камнях.

Это плохая идея инициализировать (а не запускать! Только инициализировать) поток в конструкторе?И что было бы хорошей, если не лучшей, практикой завершения потока?Обратите внимание, мне не нужно знать, как завершить поток, который работает нормально, меня скорее интересует погода, если что-то не так делать, используя одноразовый шаблон или создавая метод, который должен вызываться для завершения потока.При реализации IDisposable есть ли какие-либо вещи, которые я должен принять во внимание в отношении коллекции / очереди?

Редактировать: Поток фактически только предварительно инициализирован, чтобы предотвратить NullReferenceExceptionдобавляется в метод Enqueue, где он снова правильно инициализируется (метод Enqueue должен проверять, работает ли уже запущенный поток удаления, и, если нет, запускать новый).Обратите внимание, что всякий раз, когда все элементы сняты с производства и поток выполнил свою работу, он также больше не будет работать, поэтому каждый раз, когда очередь пуста и добавляется новый элемент, запускается новый поток для обработки очереди:

if (!_dequeuingThread.IsAlive)
{
    // start the dequeuing thread
    _dequeuingThread = new Thread(new ThreadStart(StartDequeuing));
    _dequeuingThread.Name = "DeQueueThread";
    _dequeuingThread.Start();
}

Оператору if действительно требуется инициализированный поток.Существуют и другие возможные способы достижения этого, но предварительная инициализация потока кажется наименее надоедливой.Вы видите, что после проверки погоды поток жив, чего не следует делать при предварительной инициализации, он снова правильно инициализируется.

Ответы [ 2 ]

0 голосов
/ 20 октября 2011

Кажется, есть проблема с тем фактом, что потребитель инициализирует этот объект коллекции, вызывая его конструктор, и он будет думать, что объект инициализирован (то, что должен делать конструктор), что неверно, посколькуинициализация происходит в отдельном потоке, созданном конструктором.Итак, в основном вам нужно реализовать своего рода «асинхронный API для этого объекта», чтобы инициализировать эту коллекцию так, чтобы потребитель вызывал метод initialize (после создания объекта с помощью конструктора), а затем либо передавая обратный вызов методу initialize, либозарегистрировавшись на событие в объекте коллекции, потребитель узнает, что инициализация завершена.

0 голосов
/ 20 октября 2011

Я не вижу ничего плохого в инициализации в конструкторе, но очевидно, что они будут инициализированы в другом потоке, отличном от вашего рабочего потока.

Что касается остановки, у меня обычно есть логическое значение volatileфлаг, который работник проверяет, чтобы продолжить работу.Если ваш рабочий поток вообще спит, то пусть он ожидает события, а не спит, поэтому вы можете сразу же разбудить его при остановке.

...