Я использую IBM Host Access Class Library for COM Automation как способ связи с IBM AS400 (он же iSeries, IBM i, зеленый экран, 5250) через эмулятор терминала. Я заметил, что когда вы вводите инструкцию «SendKeys», управление возвращается вашему приложению до того, как эмулятор IBM завершит выполнение команды. Это может привести к проблемам со временем, потому что вы можете отправить еще одну инструкцию «SendKeys» до того, как система будет готова ее принять.
Например:
Imports AutPSTypeLibrary
Imports AutConnListTypeLibrary
Imports AutSessTypeLibrary
Sub Example
Dim connections As New AutConnList
connections.Refresh()
If connections.Count < 1 Then Throw New InvalidOperationException("No AS400 screen can currently be found.")
Dim connection As IAutConnInfo = DirectCast(connections(1), IAutConnInfo)
_Session = New AutSess2
_Session.SetConnectionByHandle(connection.Handle)
Dim _Presentation As AutPS = DirectCast(_Session.autECLPS, AutPS)
_Presentation.SendKeys("PM70[enter]", 22, 8)
_Presentation.SendKeys("ND71221AD[enter]", 22, 20)
End Sub
будет работать правильно при пошаговом выполнении кода в отладчике, но будет давать сбой при нормальной работе, потому что вторая инструкция была отправлена слишком рано.
Один из способов работать с этим — поставить таймер или цикл после каждой команды, чтобы замедлить вызывающую программу. Я считаю это менее чем идеальным, потому что продолжительность времени не всегда предсказуема, вы часто будете ждать дольше, чем необходимо, чтобы приспособиться к случайной икоте. Это замедляет время выполнения всего процесса.
Другой способ обойти это — подождать, пока на экране не появится тестируемое состояние в результате отправленной вами команды. Иногда это будет работать, но некоторые команды не вызывают изменения экрана для проверки, и если вы хотите абстрагировать вызов команды в класс или подпрограмму, вам нужно будет указать, какое состояние экрана следует отслеживать.
Что я хотел бы найти, так это один из методов «Ждать», который будет работать в общем случае. Такие параметры, как класс autECLScreenDesc, похоже, должны быть адаптированы к очень конкретным условиям.
Класс autECLPS (также известный как AutPS) имеет несколько методов ожидания (Wait, WaitForCursor, WaitWhileCursor, WaitForString, WaitWhileString, WaitForStringInRect, WaitWhileStringInRect, WaitForAttrib, WaitWhileAttrib, WaitForScreen, WaitWhileScreen), но они также, похоже, ожидают для конкретных условий и не работают для общего случая. Общий случай важен для меня, потому что я на самом деле пытаюсь написать подпрограмму обновления поля общего назначения, которую можно вызывать из многих мест внутри и за пределами моей .dll.
Этот пример написан на VB.NET, но я ожидаю такого же поведения от C#, C++, VB6, Java; действительно все, что использует IBM Personal Communications для Windows, библиотека классов доступа к хосту версии 6.0.