2010-04-22 3 views
0

У меня есть служба Windows, которая должна работать одновременно. Я просмотрел threading и нашел класс ThreadPool. Я в настоящее время застрял, это, кажется, не имеет никакого эффекта, это похоже на то, что я в очереди, никогда не запускается или не звонит. В OnStart() событии сервиса создать нить вроде этого:C# - ThreadPool.QueueUserWorkItem() Требования

Thread mainThread = new Thread(ReceiveMessages); 
mainThread.Start(); 

Внутри методы ReceiveMessages() У меня есть процедура, которая проверяет очередь сообщений, а затем итерацию через сообщения. Для каждой итерации я вызываю следующий код, чтобы сделать некоторую работу с каждым сообщением:

ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state) 
{ 
    Interpreter.InsertMessage(encoding.GetBytes(MessageBody)); 
}), null); 

Я думаю, что синтаксис является правильным, он компилирует без проблем, но я не могу помочь, но чувствую, что я что-то отсутствует. Когда я запускаю службу, ничего не происходит. Однако, если я заменил приведенный выше фрагмент кода следующим образом:

insertThread = new Thread(delegate() { Interpreter.InsertMessage(encoding.GetBytes(MessageBody)); }); 
insertThread .Start(); 

Он работает на 100%. Это не очень эффективно, хотя может привести к сбою службы (что иногда случается, почему я пытаюсь использовать TheadPool вместо этого). Может ли кто-нибудь пролить свет на эту тему?

ответ

2

Похоже, вы создаете a closure над MessageBody в своем обратном вызове. Если свойство вызывающего пользователяMessageBody является нулевым к моменту, когда пул потоков выполняет рабочий элемент, то это то, что будет работать с InsertMessage.

Вам необходимо определить перегрузку Interpreter.InsertMessage, которая принимает объект и использовать что как ваши WaitCallback:

public void InsertMessage(object messageBody) { 
    this.InsertMessage((byte[])messageBody); 
} 

затем передать байт тела сообщения в качестве второго параметра:

ThreadPool.QueueUserWorkItem(new WaitCallback(Interpreter.InsertMessage), 
          encoding.GetBytes(MessageBody)); 
+0

Это прекрасно! Работает как шарм! –

1

По умолчанию при создании нового потока поток равен Foreground thread. Тем не менее потоки ThreadPool имеют значение IsBackground равное true.

Это означает, что нить threadpool не сохранит ваше приложение. Вероятно, поэтому он никогда не «работает» - он просто закрывается сразу.

Это не очень эффективно, хотя может привести к сбою службы (что иногда случается, почему я пытаюсь использовать TheadPool вместо этого). Может ли кто-нибудь пролить свет на эту тему?

Самосозданная нить должна быть такой же эффективной (как только поток будет работать и работает). «Сбой» никоим образом не будет помогать потоку ThreadPool - вам все равно придется отлаживать ваш сервис соответствующим образом.

+0

I понять, что вы говорите. ReceiveMessages() имеет цикл while (true), который постоянно проверяет очередь сообщений, поэтому каждый раз, когда есть сообщения, каждое сообщение получает собственный поток для выполнения некоторой работы. Возможно, это имеет какой-то эффект? –

+0

@Mr. Смит: Если основной поток завершается, вы отключите приложение (если используете потоки ThreadPool), так как вам нужно иметь хотя бы один нефонический поток, чтобы поддерживать его в памяти ... –

+0

Да, но isn ' t что я делаю в событии OnStart()?Вы сказали, что создание нового потока по умолчанию является потоком Foreground, не будет ли сделать mainThread в моем первом фрагменте кода над потоком, который сохранит его? Я использую ThreadPool внутри этого потока. Как вы думаете? –

Смежные вопросы