Все зашифровано, но вам нужно помнить, что ваш запрос останется в журналах сервера и будет доступен для различных анализаторов журналов и т. д. (что обычно не относится к запросу POST).
Вам в любом случае требуется для блокировки
, поэтому вы можете ждать
и Pulse
:
while(true) {
SomeType item;
lock(queue) {
while(queue.Count == 0) {
Monitor.Wait(queue); // releases lock, waits for a Pulse,
// and re-acquires the lock
}
item = queue.Dequeue(); // we have the lock, and there's data
}
// process item **outside** of the lock
}
с добавлением вида:
lock(queue) {
queue.Enqueue(item);
// if the queue was empty, the worker may be waiting - wake it up
if(queue.Count == 1) { Monitor.PulseAll(queue); }
}
Вы также можете посмотреть этот вопрос , который ограничивает размер очереди (блокируется, если она переполнена).
В большинстве случаев я делал это очень похоже на то, как вы настраивали, но не на том же языке. У меня было преимущество работы со структурой данных (в Python), которая блокирует поток до тех пор, пока элемент не будет помещен в очередь, что исключает необходимость вызова сна.
Если .NET предоставляет такой класс, я ' буду изучать его использование. Блокировка потока намного лучше, чем поток, вращающийся при вызовах сна.
Задание, которое вы можете передать, может быть таким же простым, как «ноль»; если код получает ноль, он знает, что пора прервать время и вернуться домой.
Если вам действительно не нужен выход из потока (и вы просто хотите, чтобы он не заставлял ваше приложение работать), вы можете установить для Thread.IsBackground значение true и он закончится, когда закончатся все не фоновые потоки. У Уилла и Марка есть хорошие решения для обработки очереди.
Вам нужен примитив синхронизации, например WaitHandle (посмотрите на статические методы). Таким образом вы можете «сигнализировать» рабочему потоку, что есть работа. Он проверяет очередь и продолжает работать до тех пор, пока она не станет пустой, после чего ожидает, пока мьютекс снова не подаст сигнал.
Сделайте один из элементов задания командой выхода, чтобы вы могли сигнализировать рабочему потоку, когда пришло время выйти из потока
Возьмите Parallel Framework . В нем есть BlockingCollection
Потоки будут заблокированы, пока в коллекции не появится элемент. Кто бы ни пришел, тот получит (зависит от процессора). Я использую это сейчас, и он отлично работает.
Он также имеет то преимущество, что он полагается на MS, чтобы написать этот особенно неприятный фрагмент кода, в котором несколько потоков обращаются к одному и тому же ресурсу. И всякий раз, когда вы можете заставить кого-нибудь написать, вы должны пойти на это. Если, конечно,
Я реализовал очередь фоновых задач без использования какого-либо цикла while
, или пульсации, или ожидания, или, действительно, касания Thread
объекты вообще. И вроде работает. (Под этим я подразумеваю, что он находился в производственных средах, обрабатывая тысячи задач в день в течение последних 18 месяцев без какого-либо неожиданного поведения.) Это класс с двумя важными свойствами: Queue
и ] BackgroundWorker
. Здесь есть три важных метода, сокращенных здесь:
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (TaskQueue.Count > 0)
{
TaskQueue[0].Execute();
}
}
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Task t = TaskQueue[0];
lock (TaskQueue)
{
TaskQueue.Remove(t);
}
if (TaskQueue.Count > 0 && !BackgroundWorker.IsBusy)
{
BackgroundWorker.RunWorkerAsync();
}
}
public void Enqueue(Task t)
{
lock (TaskQueue)
{
TaskQueue.Add(t);
}
if (!BackgroundWorker.IsBusy)
{
BackgroundWorker.RunWorkerAsync();
}
}
Дело не в том, что нет ожидания и пульсации. Но все это происходит внутри BackgroundWorker
. Он просто просыпается всякий раз, когда задача сбрасывается в очередь, выполняется до тех пор, пока очередь не станет пустой, а затем снова переходит в спящий режим.
Я далек от эксперта по многопоточности.