2015-06-25 2 views
4

У меня есть приложение, которое записывает команды на некоторые специализированные принтеры непосредственно на порт LPT1. Код выглядит следующим образом:Delphi - Как предотвратить зависание приложения при записи на LPT-порт

AssignFile(t, 'LPT1'); 
Rewrite(t); 

Write(t,#27 + '@');   // initialize 
Sleep(50);     // avoid buffer fill 
Write(t,#27#32 + Chr(0)); // set default font 
... 

Проблема заключается в том, что, когда принтер не подключен к порту, первая команда записи ничего не делает, он просто вешает трубку, и весь поток блокируется.

Есть ли способ определить тайм-аут для этих инструкций или вы можете рекомендовать другую библиотеку, которая могла бы выполнять эту работу? Было бы здорово, если бы у нее была функция Write, аналогичная функции в Delphi, потому что количество кода, использующего этот подход, очень велико, и было бы очень сложно все это изменить.

+0

Я забыл упомянуть, что «t» определяется следующим образом: var t: TextFile; –

+1

Да, есть способ определить тайм-ауты для операций на коммуникационных устройствах. См. Функции GetCommTimeouts и 'SetCommTimeouts'. –

ответ

5

Вы можете использовать SetCommTimeouts для настройки тайм-аута для ручки принтера. Чтобы получить ручку от вашего TextFile переменного типа брось в TTextRec и читать Handle поля:

var 
    CommTimeouts: TCommTimeouts; 

CommTimeouts.WriteTotalTimeoutConstant := DesiredTimeout; 
Win32Check(SetCommTimeouts(TTextRec(t).Handle, CommTimeouts)); 

Вы можете позвонить GetCommTimeouts первого, чтобы обнаружить значения по умолчанию для остальных полей, прежде чем установить те, которые вы необходимость.

+0

Спасибо большое, это сработало! –

2

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

Я бы начал с CancelSynchronousIo, что отменяет все операции ввода-вывода в заданном потоке. Это должно позволить вам сохранить все существующие звонки Write. Будьте готовы обращаться, когда они не могут быть отменены.

Для этой функции требуется Windows Vista или более поздняя версия, которая не должна быть проблемой в настоящее время, но не будет работать, если вам все еще нужна поддержка Windows XP. В этом случае вам нужно будет использовать CreateFile, чтобы открыть порт для перекрытия ввода-вывода. Затем вы можете использовать CancelIo или CancelIoEx. Вам нужно будет заменить все ваши вызовы Write, поскольку встроенные функции Delphi не поддерживают операции перекрытия.

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