![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Межпотоковое взаимодействие: есть поток, который при
AlexEgorov © (2007-04-24 09:41:00)поступленнии данных создаёт другой поток для их обработки и продолжает ждать новые данные. Как из второго потока вернуть обработанные данные в первый поток в сервисе? Если работа идёт в приложении, то Sinchronyze - и никаких проблем, а в сервисе это не прокатывает, наверное из-за того, что нет главной формы, в контексе которой работает код в Sinchronyze. Что можно сделать в сервисе?
AlexEgorov (2007-04-24 13:55:00) [1]Понятно, попробую парсинг вообще пока заменить пустыкой и пользователю отправить на тест, у меня-то всё работает на сервере с >100 принтеров и по несколько заданий в секунду... А у него и нагрузка меньше и принтеров меньше, а тем не менее возникает странная ситуация
Сергей М. (2007-04-24 13:11:00) [2]
> много случаем, когда GetJob не может помочь
>
Ну хорошо, пусть с этой точки зрения ReadPrinter будет предпочтительней.
Но я о временнойзамене ReadPrinter на GetJob с целью установить "узкое" место в алгоритме ...
AlexEgorov (2007-04-24 12:55:00) [3]Потому что мне нужно просмотреть именно содержимое задания печати, т.к. в JOB_INFO_* не всегда нужная информация есть, например количество копий для заданий отправленных из Word или для заданий отравленный с Linux/Mac/Solaris, или для заданий отправленных через IPP. В общем много случаем, когда GetJob не может помочь
Сергей М. (2007-04-24 12:05:00) [4]
> потом читается всё задание функцией ReadPrinter
Не понял ..
Почему не GetJob ?
AlexEgorov (2007-04-24 12:01:00) [5]Сначала вызывается
OpenPrinterW(PWideChar(PrnName + ',Job ' + IntToWideStr(JobId)), hPrn, nil);
потом читается всё задание функцией ReadPrinter с записью прочитанного в файл, параллельно с этим происходит парсинг, т.е. в процессе чтения. Там для разных типов заданий разные методы парсинга.
AlexEgorov (2007-04-24 12:01:00) [6]Сначала вызывается
OpenPrinterW(PWideChar(PrnName + ',Job ' + IntToWideStr(JobId)), hPrn, nil);
потом читается всё задание функцией ReadPrinter с записью прочитанного в файл, параллельно с этим происходит парсинг, т.е. в процессе чтения. Там для разных типов заданий разные методы парсинга.
Сергей М. (2007-04-24 11:46:00) [7]
> Там кода много с вызовом сопутствующих функций
А весь код и не нужен.
Интересует только фрагменты, где осуществляется чтение и запись данных задания.
AlexEgorov (2007-04-24 11:42:00) [8]Там кода много с вызовом сопутствующих функций. В общем сейчас с логами версию пользователю отправлю, может что-то прояснится, если нет то вернусь к обсуждению, спасибо
Сергей М. (2007-04-24 11:11:00) [9]
> по какой-то причине в определённый момент не срабатывает
> LeaveCriticalSection
Такого быть не может ...
Покажи, что у тебя творится в теле ParseJob ..
AlexEgorov (2007-04-24 11:02:00) [10]> Так ты защити процедуру чтения крит.секцией - и всех делов ..
Так я и сделал:
EnterCriticalSection(csJobsThread);
try
ParseJob(Job)
finally
LeaveCriticalSection(csJobsThread);
end;
Но похоже, по какой-то причине в определённый момент не срабатывает LeaveCriticalSection и обрабатывающие потоки начинают копиться :(
> Либо перенеси чтение в трансп.поток
Т.к. чтение операция небыстрая, то в момент чтения не обрабатываются новые задание печати, а когда очередь до них доходит, то они уже как правило напечатаны, т.к. небыли в паузу вовремя поставлены
Сергей М. (2007-04-24 10:57:00) [11]Уж раз чтение осуществляется в обрабатывающем потоке, то это уже совсем не обрабатывающий поток - ты там замесил и транспортные и обрабатывающие функции в одну кучу.
Либо перенеси чтение в трансп.поток (тогда защита крит.секцией не нужна), либо, как уже сказано, защищай чтение со стороны нескольких обр.потоков крит.секцией.
Сергей М. (2007-04-24 10:54:00) [12]
> то все они ломанутся на чтение содержимого заданий печати
Так ты защити процедуру чтения крит.секцией - и всех делов ..
AlexEgorov (2007-04-24 10:52:00) [13]Если каждый транспортный поток создаст свой обрабатывающий, то все они ломанутся на чтение содержимого заданий печати - вот тут и возникает торможение, особенно если задание печати здоровые (а они для плоттеров от сотни мегабайт идут). Для этого и сделан один обрабатывающий поток.
Сергей М. (2007-04-24 10:46:00) [14]А на каком этапе спулер начинает "тормозить" ?
AlexEgorov (2007-04-24 10:38:00) [15]> Каким образом ?
Приходит сообщение о новом задании печати в очереди и я ставлю задание в паузу SetJob(...). Потом дожитаюсь собития, что задание полностью встало в очередь (спулинг закончился) после этого вызываю обрабатывающий поток и продолжаю мониторить задания печати
Сергей М. (2007-04-24 10:35:00) [16]Каким образом ?
AlexEgorov (2007-04-24 10:34:00) [17]Нет, паузится не принтер, а задание печати, которое нужно парсить
Сергей М. (2007-04-24 10:33:00) [18]Pausing a printer suspends scheduling of all print jobs for that printer, exceptfor the one print job that may be currently printing.
Что на это скажешь ?
AlexEgorov (2007-04-24 10:21:00) [19]Я обрабатываю все задания печати через FindFirst/NextPrinterChangeNotification в транспортном потоке, там же поступившее задание ставится в паузу и создаётся обрабатывающий поток, котоый парсит новое задание печати и возвращает результат в транспортный поток, после этого транспортный поток делает заданию Resume, а после того, как задание напечатано, сохраняет данные о задании и ждёт следующие
Сергей М. (2007-04-24 10:18:00) [20]Какой поток у тебя вызывает EnumJobs, а какой Get/Set/AddJob ?