Собвственно есть класс для множественной работы с модемами(класс приложен к теме) так от проблемма в следующем..когда я открываю много портов модемо а потом пытаюсь их отсоиденить(тоесть закрыть их порты, а потом один из модемом тупо зависает когда исполняет CloseHandle(), и на долго, помагает токо отключение всех модемов, тогда код после CloseHandle дальше исполняеться) так от в каких случаяк может быть подвисание на CloseHandle, ОС ХР,sp 2 Класс для множественной работы с модемом в модуле TypesCreateScript.pas называеться TModem(массив одиночный модемов) Класс который предствляет одиночный модем TSony. Вот воопщем то пример Код (Text): uses windows,messages,TypesCreateScript; Var modem:TModem begin modem:=Tmodem.create; if not modem.connect('com4') then messagebox(0,'ERROR','',0); if not modem.connect('com10') then messagebox(0,'ERROR','',0); if not modem.connect('com14') then messagebox(0,'ERROR','',0); if not modem.connect('com18') then messagebox(0,'ERROR','',0); sleep(1000); modem.deconnect;//закрывает порты всех модемов,(подвисание само происходит в модуле одиночного модема) end. Вот код для закрытия порта одиночного модема: procedure TSony.Deconnect; var I:Integer; begin if Terminated_ then exit; Terminated_:=true; NamePort:=#0; if ThreadWrite_<>0 then ResumeThread(ThreadWrite_); if OverRead.hEvent<>0 then SetEvent(OverRead.hEvent); if OverWrite.hEvent<>0 then SetEvent(OverWrite.hEvent); i:=100; repeat sleep(100); dec(i); until (OverRead.hEvent = 0) and (OverWrite.hEvent = 0)and (Controled = false) or (i=0); if OverRead.hEvent <> 0 then begin CloseHandle(OverRead.hEvent); TerminateThread(ThreadRead_,0); end; if Controled then StopTimeControl; if OverWrite.hEvent<>0 then begin CloseHandle(OverWrite.hEvent); TerminateThread(ThreadWrite_,0); end; if Controled then TerminateThread(ThreadTimeControl,0); // if ThreadRead_<>0 then begin CloseHandle(ThreadRead_); ThreadRead_:=0; end; if ThreadWrite_<>0 then begin CloseHandle(ThreadWrite_); ThreadWrite_:=0; end; if ThreadTimeControl<>0 then begin CloseHandle(ThreadTimeControl); ThreadTimeControl:=0; end; if (hModem <> 0)and(hModem<>INVALID_HANDLE_VALUE) then begin CloseHandle(hModem);//подвисает гАдость!!! hModem:=0; end; FillChar(RecvData[1],Length(RecvData),0); FillChar(SendData[1],Length(SendData),0); end; Причем зависание такое сильное, что ни отладчик дельфи ни диспетчер задач не может отключит процес.. а сам отладчик дельфи пишет ошибку что тот не может завершить процес, и приходиться отключать все модемы и делать перезапуск дельфи... собственно после отключения всех модемов процес завершает свою роботу,если его до этого хотели закрыть.. а если нет, то никакой ошибки виндовс не выводит, даже после закрытия процеса... программа естественно ни при этом тож подвисает, не смотря на то что основнаяя программа работает вдругом потоке, а потоки модемом работают в потоке который порожден из основной программы в обьекте Script(но он тут не приделах, так что его я не вылажывал) когда если мы всеж хотим закрыть программу когда она подвисла(нажав на панели, правую клавишу вишы, и выбрав закрыть программу, то выскакует окно завершания программы которая зависла, потом окно отправки отчета, но если посмотреть процесы, то просец еще висит и при этом загружает комп на 100%, и держыт порты модемов открытие!) ели пытаться остановить из дельфи(или сделать паузу в дельфи) то вытает такую ошибку: Timed out waiting for process terminate если дальше нажать в этом сообщение abort получаем фатальную ошибку отладчика, и нас просят перезапустить дельфи(((
и еще заметил если также открыть порты по одному на одну копию программы, и сделать таких копий 10-20 в каждой копии будет открыт свой порт а потом через диспетчер завершать их, то не все завершаться(назвем их процес "Х") Токо часть(хотя сама форма пропадает) ! ! ! также через некоторое время пропадают и процессы "Х", а теперь если дождаться пока все процессы моей программы не пропадут из диспетчера,и поробывать удалить файл программы, то нам скажут что файл занят другой программой,от сюда вывод что процессы не доконца завершились,хотя их и не видно!!!(( а вот если отключаем все модемы, то файл программы свободно удаляеться((
XshStasX, твои посты очень тяжело даются для понимания. Буря модемных эмоций вперемешку с незакрытыми хэндлами и не до конца изученной грамматикой... Не осилил. Надеюсь с проблемой тебе помогут, но часто для этого ее надо нормально и доходчиво изложить.
deLight Что именно тяжело в понимании? Эт да, плохо знаю(( Если просто все выразить, то CloseHandle - не хотчет отдавать управление!!!(((
Можем только сказать, что проблема как-то связана с Overlapped input-output. Воможно, нужно где-нибудь вставить вызов CanelIO или что-нибудь. И, да, понять смысл первого поста можно — для этого нужно просто с минуту смотреть на текст, не пытаясь его читать.
К сожелению это тоже не помагает((( закртие порта зделал так: sleep(0);//даю системе обновиться CanelIO(hModem); sleep(100);//жду чуток чтоб все успело выполниться CloseHandle(hModem);//подвисает гАдость!!!((( hModem:=0;
Смотрится несколько не к месту среди многопоточности и overlapped input-output. А так, скорее всего, у тебя операции чтения\записи инициированы в других потоках. Посмотри описание CancelIOEx. P.S. Дальше сам — мы тебе не поможем ( теперь наши глаза закрыты x_x ).
То есть показывай минимальный исходник на котором воспроизводится проблема. А так телепаты в отпуске.
Код (Text): uses windows; type TModem = class NamePort:String; constructor Create; destructor Destroy;override; Function Connect(const port:ShortString):Boolean; Procedure DeConnect; private hCOM:THandle; dcb:TDCB; timeout:COMMTIMEOUTS; terminated_:Boolean; public property Terminated:Boolean read Terminated_; end; implementation function TModem.Connect(const port: ShortString): Boolean; begin Result:=false; if hCOM<>0 then exit; hCOM:=CreateFile(Pchar(string('\\.\'+port)),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING, FILE_FLAG_OVERLAPPED,0); if hCOM=INVALID_HANDLE_VALUE then begin hCOM:=0; exit; end; GetCommState(hCOM,dcb); GetCommTimeouts(hCOM,timeout); sleep(1); SetCommTimeouts(hCOM,timeout); SetCommState(hCOM,dcb); Result:=true; terminated_:=false; NamePort:=port; end; constructor TModem.Create; begin inherited Create; end; procedure TModem.DeConnect; begin if terminated_ then exit; terminated_:=true; CancelIo(hCOM); sleep(100); CloseHandle(hCOM); hCOM:=0; Sleep(1); end; destructor TModem.Destroy; begin inherited destroy; end; end. {--- основная программа-----} unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,read_write, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var modem:array of TModem; Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var i:Integer; begin SetLength(modem,10); for i:=0 to 9 do modem[i]:=TModem.Create; end; procedure TForm1.FormDestroy(Sender: TObject); var i:Integer; begin for i:=0 to 9 do modem[i].Destroy; end; procedure TForm1.Button1Click(Sender: TObject); const m:array [0..6] of string = ('com4','com10','com14','com18','com22','com26','com30'); var i:Integer; begin for i:=0 to 6 do begin Caption:=IntToStr(i) +'/6 - connect...'; if modem[i].Connect(m[i])=false then MessageBox(Handle,pchar(m[i]),'error connect',MB_ICONERROR or MB_SYSTEMMODAL); Caption:=IntToStr(i) +'/6 - connect'; end; end; procedure TForm1.Button2Click(Sender: TObject); var i:Integer; begin for i:=0 to 6 do begin Caption:=IntToStr(i) +'/6 - deconnect...'; modem[i].DeConnect; Caption:=IntToStr(i) +'/6 - deconnect'; sleep(500); end; end; end.
Вот маленький пример с таким зависанием. при нажатии на одну кнопку мы просто соиденяем 7 модем, на другую отсоиденяем... И через не сколько таких повторов соиденения/розсоиденения модемов, они начинают зависать на СloseHandle();,ни какой записи/чтения данных в порты модемов не делается.... зависание очень сильное так что процес который так подвис ни как нельзя завершить...надо токо сами модемы отключать от компа
Уже получше. А теперь сделай простой цикл на 1000 итераций, в котором будет только вызов CreateFile и CloseHandle. Без Sleep, без всякой другой гречихи. Попробуй подключать и "подключать" только один модем. Попробуй убрать FILE_FLAG_OVERLAPPED. Кстати, какая ось?
Ну вот один модем выдержал 4000 CreateFile/CloseHandle Когда подключил уже два их то на 3разе зависание.... Но по одному они работают без проблем. Модемы Телефоны SE w200,k510,k320
Аналогично. Была у нас когда-то телефона этой фирмы – устройство периодически "пропадало" при передаче файлов, например. Хотя, возможно, то были её хардварные проблемы.