-1
私は、起動時にアプリケーションを応答させるためにTTaskを使用して、DBを更新します。 アプリケーションが起動すると、DB更新フォームが開始され、いくつかの手順が順番に実行され、更新の進行状況(ProgrssBar1)も表示されます。すべての手順は専用ユニットに配置されています。コード例:DelphiのTTask - 1つのプロシージャが実行されない
procedure TfrmUpdate.FormActivate(Sender: TObject);
var
TasksUpdate: array [0..5] of ITask;
begin
TasksUpdate[0]:= TTask.Create(procedure
begin
// Unit1.procedure1
TThread.Synchronize(nil, procedure
begin
ProgressBar1.StepBy(20);
end);
end);
TasksUpdate[0].Start;
TasksUpdate[1]:= TTask.Create(procedure
begin
TTask.WaitForAny(TasksUpdate[0]);
// Unit1.procedure2
TThread.Synchronize(nil, procedure
begin
ProgressBar1.StepBy(20);
end);
end);
TasksUpdate[1].Start;
TasksUpdate[2]:= TTask.Create(procedure
begin
TTask.WaitForAny(TasksUpdate[1]);
// Unit1.procedure3
TThread.Synchronize(nil,procedure
begin
ProgressBar1.StepBy(20);
end);
end);
TasksUpdate[2].Start;
TasksUpdate[3]:= TTask.Create(procedure
begin
TTask.WaitForAny(TasksUpdate[2]);
// Unit1.procedure4
TThread.Synchronize(nil,procedure
begin
ProgressBar1.StepBy(20);
end);
end);
TasksUpdate[3].Start;
TasksUpdate[4]:= TTask.Create(procedure
begin
TTask.WaitForAny(TasksUpdate[3]);
// Unit1.procedure5
TThread.Synchronize(nil,procedure
begin
ProgressBar1.StepBy(20);
end);
end);
TasksUpdate[4].Start;
TasksUpdate[5]:= TTask.Create(procedure
begin
TTask.WaitForAny(TasksUpdate[4]);
ProgressBar1.StepBy(100);
Sleep(1000);
frmUpdate.Close;
end);
TasksUpdate[5].Start;
end;
すべてのプロシージャは1つを除いて正常に実行されます。この手順を直接実行すると、完全に機能します。たぶんTTaskとしてプロシージャを実行するいくつかの制限がありますか? 問題の手順コード:
procedure Update_Currency_Rate;
var
aStream: TMemoryStream;
Params: TStringStream;
uzklausa1, uzklausa2: string;
RateList: IXMLFxRatesType;
ResK, i, y, Day: integer;
k_data: TDate;
DS6: TZQuery;
begin
FormatSettings.DateSeparator:= '-';
DS6:= TZQuery.Create(nil);
DS6.Connection:= frmConnection.ZConnection1;
with DS6 do
begin
Close;
SQL.Clear;
SQL.Add('query');
Open;
end;
if DS6.FieldValues['data'] = 'yes' then
begin
with DS6 do
begin
Close;
SQL.Clear;
SQL.Add('some query');
Open;
end;
k_data:= DS6.FieldByName('buh_data').AsDateTime;
if DayOfWeek(Date).ToString = '7' then
k_data:= k_data + 1;
if DayOfWeek(Date).ToString = '1' then
k_data:= k_data + 2;
ResK:= CompareDate(k_data, Date);
if (ResK < 0) then
begin
Day:= 0;
ResK:= CompareTime(StrToTime('15:15:00'), Now);
if (ResK <= 0) then
Day:= -1;
if DayOfWeek(Date).ToString = '7' then
Day:= Day -1;
if DayOfWeek(Date).ToString = '1' then
Day:= Day -2;
iHTTP:= TIdHTTP.Create(nil);
XMLDoc1:= TXMLDocument.Create(nil);
aStream := TMemoryStream.create;
Params := TStringStream.create('');
try
with iHTTP do
begin
Params.WriteString(URLEncode(...));
Request.ContentType := 'application/x-www-form-urlencoded';
Request.CharSet := 'utf-8';
try
Response.KeepAlive := False;
Post('http://...', Params, aStream);
except
on E: Exception do
begin
Exit;
end;
end;
end;
aStream.WriteBuffer(#0' ', 1);
except
aStream.Free;
Params.Free;
Exit;
end;
frmConnection.ZConnection1.StartTransaction;
try
with DS6 do
begin
Close;
SQL.Clear;
SQL.Add('DROP TABLE IF EXISTS ...');
ExecSQL;
end;
with DS6 do
begin
Close;
SQL.Clear;
SQL.Add('CREATE TEMPORARY TABLE ...)');
ExecSQL;
end;
with DS6 do
begin
Close;
SQL.Clear;
SQL.Add('some query');
Open;
end;
if DS6.FieldValues['p_data'] = NULL then
y:= 0
else
y:= 1;
RemoveNullFromMemoryStream(aStream);
XMLDoc1.LoadFromStream(aStream);
RateList:= GetFxRates(XMLDoc1);
for i:= 0 to RateList.Count - 1 do
begin
with DS6 do
begin
Close;
SQL.Clear;
SQL.Add('some query');
ExecSQL;
uzklausa1:= 'insert_query';
uzklausa2:= 'update_query';
SQL.Clear;
if y = 0 then
SQL.Add(q1)
else
SQL.Add(q2);
ExecSQL;
end;
end;
Day:= 0;
if (ResK <= 0) and ((DayOfWeek(Date).toString <> '1') or (DayOfWeek(Date).toString <> '7')) then
Day:= 0;
if (DayOfWeek(Date).toString = '1') then
Day:= Day - 2;
if (DayOfWeek(Date).toString = '7') then
Day:= Day - 1;
with DS6 do
begin
Close;
SQL.Clear;
SQL.Add('some query');
ExecSQL;
end;
frmConnection.ZConnection1.Commit;
except
on E: Exception do
begin
frmConnection.ZConnection1.Rollback;
end;
end;
end;
end;
end;
しないでくださいすべての例外を抑制する。それらを流して、あなたが間違っていることについての詳細をいくつか得るでしょう –
BTWあなたは他のスレッドの中のメインスレッドからdb接続を使用してはいけません。 –
はい、TADOConnectionはスレッドセーフではありません。あなたは新しいスレッドにentiry接続文字列を渡す必要があります – Zam