![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблемы с OLE DB [D7, WinXP]
GanibalLector © (2005-06-30 00:28:00)Угораздило меня связаться с 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.
evvcom (2005-07-01 14:20:00) [1]
> и жду его завершения
Где ты его ждешь?
> Я НЕ ЗАПУСКАЮ несколько
Основной поток + доп.поток = уже несколько.
Не веришь - не верь, проблема от этого не рассосется. Она время от времени будет проявляться одноразовыми падениями твоей программы, но это можно будет списать на нелицензионность винды, на установку дополнительных левых программ и т.п.
Использование sleep разгрузило занятость твоего процессора и снизило вероятность [13] и ничего более.
GanibalLector (2005-07-01 14:08:00) [2]2 evvcom © (01.07.05 08:26) [13]
Я запускаю доп.поток и жду его завершения. Я НЕ ЗАПУСКАЮ несколько.
evvcom (2005-07-01 08:26:00) [3]
> Вы будете смеятся,но sleep(100) помогло. Теперь все работает
> на всех компах.
sleep резко снизил вероятность одновременного обращения из разных потоков к каким-то данным. Работает, но время от времени будут случаться глюки, причину которых ты так и не устранил.
GanibalLector (2005-06-30 23:34:00) [4]Вы будете смеятся,но sleep(100) помогло. Теперь все работает на всех компах. Чудеса просто какие-то!!! Я вот до сих пор не пойму причин.
Я вот что думаю : при Connect моя программа всегда теряет фокус...видать COM активизируется. Без sleep(100) может он не успевает что-то сделать. Чудеса да и только,блин ;)
Erik1 (2005-06-30 11:53:00) [5]Кстати можно глянуть какие потоки у тебя активны Process Explorer тебе покажет. А чтобы назличить потоки создай там именованые ресурсы.
Digitman (2005-06-30 09:26:00) [6]
> в ф-ции 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;
GanibalLector (2005-06-30 09:10:00) [7]Ребята,в общем если поток будет такой :
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 будет зависать.
evvcom (2005-06-30 09:06:00) [8]
> К визуальным компонентам из потока я не обращаюсь
А это не визуальные компоненты?
> Conn:=Connect( Form2.ComboBox1.Text,Form2.ComboBox2.Text,
> Form2.ELogin.Text, Form2.EPassword.Text);
...
> Grid.Add(...
И к невизуальным тоже нельзя обращаться, т.к. они сами извещают визуальные об изменениях и соответственно обращаются.
GanibalLector (2005-06-30 09:06:00) [9]2 sniknik,Digitman
в ф-ции Connect обращаюсь только для чтения!!! Для чтения можно ведь ;)
>а Grid: TStringGrid ?
нет Grid:TObjectList
Digitman (2005-06-30 09:03:00) [10]
> К визуальным компонентам из потока я не обращаюсь
а это что по твоему
> Conn:=Connect(Form2.ComboBox1.Text,Form2.ComboBox2.Text,
> Form2.ELogin.Text, Form2.EPassword.Text);
?
а Grid: TStringGrid ?
sniknik (2005-06-30 09:01:00) [11]> Нет,не обращаюсь!
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;
GanibalLector (2005-06-30 08:59:00) [12]2 sniknik
>без синхронизации в потоке обращаешся к компонентам формы из VCL?
Нет,не обращаюсь!
>зачем так часто? вставь гденибудь в цикле sleep(100) хотябы.
Хорошо,вставлю.
Кстати,при зависании потока загрузка процессора 100%
sniknik (2005-06-30 08:56:00) [13]без синхронизации в потоке обращаешся к компонентам формы из VCL?
может быть причиной.
//где-то в коде
repeat
Application.ProcessMessages;
GetExitCodeThread(hThread,ECode);
until ECode<>STILL_ACTIVE;
зачем так часто? вставь гденибудь в цикле sleep(100) хотябы.
GanibalLector (2005-06-30 08:54:00) [14]2 Digitman
А что не так? ИМХО,все правильно. К визуальным компонентам из потока я не обращаюсь.
Digitman (2005-06-30 08:49:00) [15]забудь на время про свой ADO и приведи свой алгоритм в соответствие с рекомендациями Борланда по потокобезопасной работе с VCL-объектами