Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.07.18;
Скачать: CL | DM;

Вниз

Проблемы с OLE DB   Найти похожие ветки 

 
GanibalLector ©   (2005-06-30 00:28) [0]

Угораздило меня связаться с OLE DB провайдером :(
Написал...запускаю из IDE все ВСЕГДА ОТЛИЧНО работает, запускаю exe - зависание потока(причем не всегда!!!То зависает, то не зависает.)

Начал разбираться. Имею следующее :
-на трех компьютерах нижеизлагающийся сабж прекрасно работает, в тоже время на четвертом самопроизвольно зависает мой поток(т.е.запускал раз 50...если хотя бы один раз поток завис, то после убиения программы 3 клавишами и повторного запуска поток зависает намного чаще: из 10 запусков 1 раз).Если убрать из сабжа Conn:=nil; то получаю совершенно обратную картину: на тех трех компьютерах сабж постоянно зависает, а на том четвертом прекрасно работает.
-понаставил  try...except на все команды в потоке. При зависании потока ни одного вхождения в except не произшло.Чудеса!!!
-понаставил Windows.Beep(500,100) после каждой команды и ВЫЯСНИЛ, что Connect при зависании не выполняется!

Копаю несколько дней :( уже и варианты все закончились. Что скажите???
Итак, сабж :

...
function potok(Param: Pointer): DWord;
 var Conn:_Connection;
     Ob:TObjectList;
     I:Integer;
begin
 CoInitialize(nil);
 Conn:=Connect(Form2.ComboBox1.Text,Form2.ComboBox2.Text,
               Form2.ELogin.Text,  Form2.EPassword.Text);

    Ob:=ReadTable(Conn,PChar(Param));
    //
  for i:=0 to Ob.Count-1 do
  begin
    Grid.Add(TStringList.Create);
    TStrings(Grid.Items[i]).Clear;
    TStrings(Grid.Items[i]).AddStrings(TStrings(Ob.Items[i]));
  end;
  Ob.Free;
  MySound(Conn);
  Conn.Close;
  Conn:=nil;// причина моих неудач???
CoUninitialize;
Result:=0;
end;
...
//где-то в коде
procedure TFWait.TableRead(Grid: TStringGrid; Table: String);
var hThread:HWND;
   ThreadID,ECode:DWord;
begin
 hThread:=BeginThread(nil,0,@potok,Pchar(Table),0,ThreadID);
 repeat
   Application.ProcessMessages;
   GetExitCodeThread(hThread,ECode);
 until  ECode<>STILL_ACTIVE;
 CloseHandle(hThread);
   SetGrid(Grid);
 ModalResult:=mrOk;
end;


а вот еще один модуль:

...
function Connect(Port,Baud,Login,Pas:String):_Connection;
begin
  Result:=CoConnection.Create;
  with Result do
  begin
    Provider:="EQL OLE DB Provider";
    Properties["DBMS Name"].Value:="L2Com.HcComSessionCreator";
    Open(Port+";0;"+Baud+";",Login,Pas,Integer(adConnectUnspecified));
  end;
end;

function ReadTable(Conn:_Connection;NameTable:String):TObjectList;
 var
  Table:_RecordSet;
  i:Integer;
  FieldList:TStringList;
begin
 Table:=CoRecordSet.Create;
 Table.Open(NameTable,Conn,adOpenStatic,adLockReadOnly,adCmdTableDirect);
 Result:=TObjectList.Create;

   for i:=0 to Table.Fields.Count-1 do
   begin
     Table.MoveFirst;
     FieldList:=TStringList.Create;
     while not Table.EOF do
      begin
        FieldList.Add(Table.Fields[i].Value);
        Table.MoveNext;
      end;
     Result.Add(FieldList);
   end;
 Table.Close;
end;

procedure MySound(Conn:_Connection);
 var Table:_RecordSet;
 Procitf:Variant;
 ifnp:IHcSound;
begin
 Table:=CoRecordSet.Create;
 Table.Open("EQL_service",Conn,adOpenUnspecified,adLockUnspecified,adCmdTableDirect);
 Procitf:=Table.Fields["Procedure"].Value;

 {$IFDEF ADOVERCHECK}
 Val(Conn.Version,ADOVer,ErrCode);
 if (ErrCode<>0) or (ADOVer<2.6) then
 begin
   IDispatch(TVarData(procitf).VDispatch)._Release;
   IDispatch(TVarData(procitf).VDispatch)._Release;
 end;
 {$ENDIF}

  if Supports(procitf,IHcSound,ifnp) then
  begin
    ifnp.OutTone(45,1000);
    ifnp.OutTone(20,870);
    ifnp.OutTone(45,1000);
  end;
 Table.Close;
end;



З.Ы. Разработчик этого OLE DB говорит,что проблемы могут возникать на Delphi5 с версией ADO 2.5 и ниже.
Во избежании этих проблем он рекомендует делать {$IFDEF ADOVERCHECK} в моем сабже это есть.Но только у меня D7,ADO версии 2.8.


 
Digitman ©   (2005-06-30 08:49) [1]

забудь на время про свой ADO и приведи свой алгоритм в соответствие с рекомендациями Борланда по потокобезопасной работе с VCL-объектами


 
GanibalLector ©   (2005-06-30 08:54) [2]

2 Digitman
А что не так? ИМХО,все правильно. К визуальным компонентам из потока я не обращаюсь.


 
sniknik ©   (2005-06-30 08:56) [3]

без синхронизации в потоке обращаешся к компонентам формы из VCL?
может быть причиной.

//где-то в коде
repeat
  Application.ProcessMessages;
  GetExitCodeThread(hThread,ECode);
until  ECode<>STILL_ACTIVE;
зачем так часто? вставь гденибудь в цикле sleep(100) хотябы.


 
GanibalLector ©   (2005-06-30 08:59) [4]

2 sniknik
>без синхронизации в потоке обращаешся к компонентам формы из VCL?
Нет,не обращаюсь!

>зачем так часто? вставь гденибудь в цикле sleep(100) хотябы.
Хорошо,вставлю.

Кстати,при зависании потока загрузка процессора 100%


 
sniknik ©   (2005-06-30 09:01) [5]

> Нет,не обращаюсь!
function potok(Param: Pointer): DWord;
var Conn:_Connection;
    Ob:TObjectList;
    I:Integer;
begin
CoInitialize(nil);
Conn:=Connect(Form2.ComboBox1.Text,Form2.ComboBox2.Text,
              Form2.ELogin.Text,  Form2.EPassword.Text
);
   Ob:=ReadTable(Conn,PChar(Param));
   //
 for i:=0 to Ob.Count-1 do
 begin
   Grid.Add(TStringList.Create);
   TStrings(Grid.Items[i]).Clear;
   TStrings(Grid.Items[i]).AddStrings(TStrings(Ob.Items[i]));

 end;
 Ob.Free;
 MySound(Conn); //под вопросом
 Conn.Close;
 Conn:=nil;// причина моих неудач???
CoUninitialize;
Result:=0;
end;


 
Digitman ©   (2005-06-30 09:03) [6]


> К визуальным компонентам из потока я не обращаюсь


а это что по твоему


> Conn:=Connect(Form2.ComboBox1.Text,Form2.ComboBox2.Text,
>                Form2.ELogin.Text,  Form2.EPassword.Text);


?

а Grid: TStringGrid ?


 
evvcom ©   (2005-06-30 09:06) [7]


> К визуальным компонентам из потока я не обращаюсь

А это не визуальные компоненты?

> Conn:=Connect(Form2.ComboBox1.Text,Form2.ComboBox2.Text,
>                Form2.ELogin.Text,  Form2.EPassword.Text
);
...
> Grid.Add(...

И к невизуальным тоже нельзя обращаться, т.к. они сами извещают визуальные об изменениях и соответственно обращаются.


 
GanibalLector ©   (2005-06-30 09:06) [8]

2 sniknik,Digitman

в ф-ции Connect обращаюсь только для чтения!!! Для чтения можно ведь ;)

>а Grid: TStringGrid ?
нет Grid:TObjectList


 
GanibalLector ©   (2005-06-30 09:10) [9]

Ребята,в общем если поток будет такой :

function potok(Param: Pointer): DWord;
var Conn:_Connection;
    Ob:TObjectList;
    I:Integer;
begin
CoInitialize(nil);
Conn:=Connect("2","38400","1","0");
 MySound(Conn);
 Conn.Close;
 Conn:=nil;// причина моих неудач???
CoUninitialize;
Result:=0;
end;


то все-равно exe будет зависать.


 
Digitman ©   (2005-06-30 09:26) [10]


> в ф-ции Connect обращаюсь только для чтения


вызов Connect() - не мгновенная операция !!


> нет Grid:TObjectList


тогда устрани чехарду с одинаковыми именами идентификаторов совершенно разных объектов)

function potok(Param: Pointer): DWord;
var Conn:_Connection;
   Ob:TObjectList;
   I:Integer;
begin
try
CoInitialize(nil);
try
 Conn:=Connect("2","38400","1","0");
 try
   try
     MySound(Conn);
     Result:=0;
   finally
     Conn.Close;
   end;
 finally
   Conn:=nil;// причина моих неудач???
 end;
finally
 CoUninitialize;
end;
except
.. запись в протокол непредвиденных искл.ситуаций в трэде ...
end;
end;


 
Erik1 ©   (2005-06-30 11:53) [11]

Кстати можно глянуть какие потоки у тебя активны Process Explorer тебе покажет. А чтобы назличить потоки создай там именованые ресурсы.


 
GanibalLector ©   (2005-06-30 23:34) [12]

Вы будете смеятся,но sleep(100) помогло. Теперь все работает на всех компах. Чудеса просто какие-то!!! Я вот до сих пор не пойму причин.

Я вот что думаю : при Connect моя программа всегда теряет фокус...видать COM активизируется. Без sleep(100) может он не успевает что-то сделать. Чудеса да и только,блин ;)


 
evvcom ©   (2005-07-01 08:26) [13]


> Вы будете смеятся,но sleep(100) помогло. Теперь все работает
> на всех компах.

sleep резко снизил вероятность одновременного обращения из разных потоков к каким-то данным. Работает, но время от времени будут случаться глюки, причину которых ты так и не устранил.


 
GanibalLector ©   (2005-07-01 14:08) [14]

2 evvcom ©   (01.07.05 08:26) [13]
Я запускаю доп.поток и жду его завершения. Я НЕ ЗАПУСКАЮ несколько.


 
evvcom ©   (2005-07-01 14:20) [15]


> и жду его завершения

Где ты его ждешь?

> Я НЕ ЗАПУСКАЮ несколько

Основной поток + доп.поток = уже несколько.

Не веришь - не верь, проблема от этого не рассосется. Она время от времени будет проявляться одноразовыми падениями твоей программы, но это можно будет списать на нелицензионность винды, на установку дополнительных левых программ и т.п.

Использование sleep разгрузило занятость твоего процессора и снизило вероятность [13] и ничего более.



Страницы: 1 вся ветка

Текущий архив: 2005.07.18;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.086 c
1-1120329248
heady
2005-07-02 22:34
2005.07.18
Окно без появления на панели задач (диалог)


3-1117655097
alex-drob
2005-06-01 23:44
2005.07.18
WideString actual: Integer - Почему


4-1116935485
Antonn
2005-05-24 15:51
2005.07.18
Синхронизация времени в Internet


5-1090308239
Death_R
2004-07-20 11:23
2005.07.18
Создание компонента при изменении свойств другого компонента


14-1119618538
VMcL
2005-06-24 17:08
2005.07.18
Ну вот, учёба закончилась