C # - ThreadPool.QueueUserWorkItem () Требования - PullRequest
0 голосов
/ 23 апреля 2010

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

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 ]

2 голосов
/ 23 апреля 2010

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

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

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

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

ThreadPool.QueueUserWorkItem(new WaitCallback(Interpreter.InsertMessage), 
                             encoding.GetBytes(MessageBody));
1 голос
/ 23 апреля 2010

По умолчанию, когда вы создаете новый поток, потоком является основной поток . Тем не менее, для потоков ThreadPool IsBackground установлено значение true.

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

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

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

...