зависание на CloseHandle()

Тема в разделе "WASM.BEGINNERS", создана пользователем XshStasX, 25 апр 2009.

  1. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Собвственно есть класс для множественной работы с модемами(класс приложен к теме)
    так от проблемма в следующем..когда я открываю много портов модемо
    а потом пытаюсь их отсоиденить(тоесть закрыть их порты, а потом один из модемом тупо зависает когда исполняет CloseHandle(), и на долго, помагает токо отключение всех модемов, тогда код после CloseHandle дальше исполняеться)
    так от в каких случаяк может быть подвисание на CloseHandle, ОС ХР,sp 2
    Класс для множественной работы с модемом в модуле TypesCreateScript.pas называеться TModem(массив одиночный модемов)
    Класс который предствляет одиночный модем TSony.
    Вот воопщем то пример
    Код (Text):
    1. uses
    2.  windows,messages,TypesCreateScript;
    3. Var
    4.  modem:TModem
    5. begin
    6. modem:=Tmodem.create;
    7. if not modem.connect('com4') then
    8.  messagebox(0,'ERROR','',0);
    9. if not modem.connect('com10') then
    10.  messagebox(0,'ERROR','',0);
    11. if not modem.connect('com14') then
    12.  messagebox(0,'ERROR','',0);
    13. if not modem.connect('com18') then
    14.  messagebox(0,'ERROR','',0);
    15. sleep(1000);
    16. modem.deconnect;//закрывает порты всех модемов,(подвисание само происходит в модуле одиночного модема)
    17. end.
    18.  
    19. Вот код для закрытия порта одиночного модема:
    20. procedure TSony.Deconnect;
    21. var
    22.  I:Integer;
    23. begin
    24. if Terminated_ then exit;
    25.  Terminated_:=true;
    26. NamePort:=#0;
    27. if ThreadWrite_<>0 then
    28.  ResumeThread(ThreadWrite_);
    29. if OverRead.hEvent<>0 then
    30.  SetEvent(OverRead.hEvent);
    31. if OverWrite.hEvent<>0 then
    32.  SetEvent(OverWrite.hEvent);
    33.  i:=100;
    34. repeat
    35. sleep(100);
    36. dec(i);
    37. until (OverRead.hEvent = 0) and (OverWrite.hEvent = 0)and (Controled = false) or (i=0);
    38. if OverRead.hEvent <> 0  then
    39. begin
    40.   CloseHandle(OverRead.hEvent);
    41.  TerminateThread(ThreadRead_,0);
    42. end;
    43. if Controled then
    44.  StopTimeControl;
    45. if OverWrite.hEvent<>0 then
    46. begin
    47.   CloseHandle(OverWrite.hEvent);
    48.  TerminateThread(ThreadWrite_,0);
    49. end;
    50. if Controled then
    51.  TerminateThread(ThreadTimeControl,0);
    52. //
    53. if ThreadRead_<>0 then
    54. begin
    55.  CloseHandle(ThreadRead_);
    56.  ThreadRead_:=0;
    57. end;
    58. if ThreadWrite_<>0 then
    59. begin
    60.  CloseHandle(ThreadWrite_);
    61.  ThreadWrite_:=0;
    62. end;
    63. if ThreadTimeControl<>0 then
    64. begin
    65.  CloseHandle(ThreadTimeControl);
    66.  ThreadTimeControl:=0;
    67. end;
    68. if (hModem <> 0)and(hModem<>INVALID_HANDLE_VALUE) then
    69. begin
    70.  CloseHandle(hModem);//подвисает гАдость!!!
    71.  hModem:=0;
    72. end;
    73. FillChar(RecvData[1],Length(RecvData),0);
    74. FillChar(SendData[1],Length(SendData),0);
    75. end;
    Причем зависание такое сильное, что ни отладчик дельфи ни диспетчер задач не может отключит процес..
    а сам отладчик дельфи пишет ошибку что тот не может завершить процес, и приходиться отключать все модемы и делать перезапуск дельфи...
    собственно после отключения всех модемов процес завершает свою роботу,если его до этого хотели закрыть..
    а если нет, то никакой ошибки виндовс не выводит, даже после закрытия процеса...
    программа естественно ни при этом тож подвисает, не смотря на то что основнаяя программа работает вдругом потоке, а потоки модемом работают в потоке который порожден из основной программы в обьекте Script(но он тут не приделах, так что его я не вылажывал)
    когда если мы всеж хотим закрыть программу когда она подвисла(нажав на панели, правую клавишу вишы, и выбрав закрыть программу, то выскакует окно завершания программы которая зависла, потом окно отправки отчета, но если посмотреть процесы, то просец еще висит и при этом загружает комп на 100%, и держыт порты модемов открытие!)
    ели пытаться остановить из дельфи(или сделать паузу в дельфи)
    то вытает такую ошибку:
    Timed out waiting for process terminate
    если дальше нажать в этом сообщение abort
    получаем фатальную ошибку отладчика, и нас просят перезапустить дельфи(((
     
  2. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    и еще заметил если также открыть порты по одному на одну копию программы, и сделать таких копий 10-20
    в каждой копии будет открыт свой порт
    а потом через диспетчер завершать их, то не все завершаться(назвем их процес "Х")
    Токо часть(хотя сама форма пропадает) ! ! !
    также через некоторое время пропадают и процессы "Х", а теперь если дождаться пока все процессы моей программы не пропадут из диспетчера,и поробывать удалить файл программы, то нам скажут что файл занят другой программой,от сюда вывод что процессы не доконца завершились,хотя их и не видно!!!((
    а вот если отключаем все модемы, то файл программы свободно удаляеться((
     
  3. deLight

    deLight New Member

    Публикаций:
    0
    Регистрация:
    26 май 2008
    Сообщения:
    879
    XshStasX, твои посты очень тяжело даются для понимания.
    Буря модемных эмоций вперемешку с незакрытыми хэндлами и не до конца изученной грамматикой... Не осилил. Надеюсь с проблемой тебе помогут, но часто для этого ее надо нормально и доходчиво изложить.
     
  4. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    deLight
    Что именно тяжело в понимании?
    Эт да, плохо знаю((
    Если просто все выразить, то CloseHandle - не хотчет отдавать управление!!!(((
     
  5. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Можем только сказать, что проблема как-то связана с Overlapped input-output. Воможно, нужно где-нибудь вставить вызов CanelIO или что-нибудь. И, да, понять смысл первого поста можно — для этого нужно просто с минуту смотреть на текст, не пытаясь его читать.
     
  6. deLight

    deLight New Member

    Публикаций:
    0
    Регистрация:
    26 май 2008
    Сообщения:
    879
    желательно с закрытыми глазами.
     
  7. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    К сожелению это тоже не помагает(((
    закртие порта зделал так:
    sleep(0);//даю системе обновиться
    CanelIO(hModem);
    sleep(100);//жду чуток чтоб все успело выполниться
    CloseHandle(hModem);//подвисает гАдость!!!(((
    hModem:=0;
     
  8. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Смотрится несколько не к месту среди многопоточности и overlapped input-output.
    А так, скорее всего, у тебя операции чтения\записи инициированы в других потоках.
    Посмотри описание CancelIOEx.

    P.S.
    Дальше сам — мы тебе не поможем ( теперь наши глаза закрыты x_x ).
     
  9. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    ...Тоесть?
     
  10. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    То есть показывай минимальный исходник на котором воспроизводится проблема.
    А так телепаты в отпуске.
     
  11. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Код (Text):
    1. uses
    2.  windows;
    3. type
    4. TModem = class
    5.  NamePort:String;
    6. constructor Create;
    7. destructor Destroy;override;
    8. Function Connect(const port:ShortString):Boolean;
    9. Procedure DeConnect;
    10. private
    11.  hCOM:THandle;
    12.  dcb:TDCB;
    13.  timeout:COMMTIMEOUTS;
    14.  terminated_:Boolean;
    15. public
    16.  property Terminated:Boolean read Terminated_;
    17. end;
    18. implementation
    19. function TModem.Connect(const port: ShortString): Boolean;
    20. begin
    21. Result:=false;
    22. if hCOM<>0 then exit;
    23. hCOM:=CreateFile(Pchar(string('\\.\'+port)),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING, FILE_FLAG_OVERLAPPED,0);
    24. if hCOM=INVALID_HANDLE_VALUE then
    25. begin
    26.  hCOM:=0;
    27.  exit;
    28. end;
    29.  GetCommState(hCOM,dcb);
    30.  GetCommTimeouts(hCOM,timeout);
    31.  sleep(1);
    32.  SetCommTimeouts(hCOM,timeout);
    33.  SetCommState(hCOM,dcb);
    34. Result:=true;
    35. terminated_:=false;
    36. NamePort:=port;
    37. end;
    38. constructor TModem.Create;
    39. begin
    40.  inherited Create;
    41. end;
    42. procedure TModem.DeConnect;
    43. begin
    44. if terminated_ then exit;
    45. terminated_:=true;
    46. CancelIo(hCOM);
    47. sleep(100);
    48. CloseHandle(hCOM);
    49. hCOM:=0;
    50. Sleep(1);
    51. end;
    52. destructor TModem.Destroy;
    53. begin
    54.   inherited destroy;
    55. end;
    56. end.
    57. {---         основная программа-----}
    58. unit Unit1;
    59.  
    60. interface
    61.  
    62. uses
    63.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    64.   Dialogs,read_write, StdCtrls;
    65.  
    66. type
    67.   TForm1 = class(TForm)
    68.     Button1: TButton;
    69.     Button2: TButton;
    70.     procedure FormCreate(Sender: TObject);
    71.     procedure FormDestroy(Sender: TObject);
    72.     procedure Button1Click(Sender: TObject);
    73.     procedure Button2Click(Sender: TObject);
    74.   private
    75.     { Private declarations }
    76.   public
    77.     { Public declarations }
    78.   end;
    79.  
    80. var
    81. modem:array of TModem;
    82.   Form1: TForm1;
    83.  
    84. implementation
    85.  
    86. {$R *.dfm}
    87.  
    88. procedure TForm1.FormCreate(Sender: TObject);
    89. var
    90.  i:Integer;
    91. begin
    92. SetLength(modem,10);
    93. for i:=0 to 9 do
    94.  modem[i]:=TModem.Create;
    95. end;
    96.  
    97. procedure TForm1.FormDestroy(Sender: TObject);
    98. var
    99.  i:Integer;
    100. begin
    101.  
    102. for i:=0 to 9 do
    103.  modem[i].Destroy;
    104. end;
    105.  
    106. procedure TForm1.Button1Click(Sender: TObject);
    107. const
    108.  m:array [0..6] of string = ('com4','com10','com14','com18','com22','com26','com30');
    109. var
    110.  i:Integer;
    111. begin
    112. for i:=0 to 6 do
    113. begin
    114. Caption:=IntToStr(i) +'/6 - connect...';
    115. if modem[i].Connect(m[i])=false then
    116.  MessageBox(Handle,pchar(m[i]),'error connect',MB_ICONERROR or MB_SYSTEMMODAL);
    117. Caption:=IntToStr(i) +'/6 - connect';
    118. end;     end;
    119.  
    120. procedure TForm1.Button2Click(Sender: TObject);
    121. var
    122.  i:Integer;        
    123. begin
    124.  for i:=0 to 6 do
    125.  begin
    126.  Caption:=IntToStr(i) +'/6 - deconnect...';
    127.   modem[i].DeConnect;
    128.   Caption:=IntToStr(i) +'/6 - deconnect';
    129.   sleep(500);
    130.  end;
    131. end;
    132.  
    133. end.
     
  12. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Вот маленький пример с таким зависанием.
    при нажатии на одну кнопку мы просто соиденяем 7 модем, на другую отсоиденяем...
    И через не сколько таких повторов соиденения/розсоиденения модемов, они начинают зависать на СloseHandle();,ни какой записи/чтения данных в порты модемов не делается....
    зависание очень сильное так что процес который так подвис ни как нельзя завершить...надо токо сами модемы отключать от компа
     
  13. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Уже получше. А теперь сделай простой цикл на 1000 итераций, в котором будет только вызов CreateFile и CloseHandle. Без Sleep, без всякой другой гречихи. Попробуй подключать и "подключать" только один модем. Попробуй убрать FILE_FLAG_OVERLAPPED.
    Кстати, какая ось?
     
  14. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Ось XP sp2
     
  15. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Ну вот один модем выдержал 4000 CreateFile/CloseHandle
    Когда подключил уже два их то на 3разе зависание....
    Но по одному они работают без проблем.
    Модемы Телефоны SE w200,k510,k320
     
  16. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    Мое мнение все больше склоняеться к тому что, виноват тут драйвер для телефона...
     
  17. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Аналогично. Была у нас когда-то телефона этой фирмы – устройство периодически "пропадало" при передаче файлов, например. Хотя, возможно, то были её хардварные проблемы.
     
  18. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    А ручное написание драйвера для тел. чтоб тот работал как ком модем,долгое дело?
     
  19. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Йюп. Десятки килобайт компилированного кода. На своём месте мы бы не стали пытаться.