Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > закачка данных отдельным потоком


Автор: rOOxus 28.4.2009, 15:14
здравствуйте коллеги!
пишу программку для закачки данных из DBF файла в БД FireBird. Идея следующая: доступ к DBF средствами BDE через TTable, в БД есть процедура параметры которой имеют те же имена, что и поля DBF-таблицы и которая осуществляет преобразования этих полей а так же распихивает их данные по разным таблицам. По Table1 организован цикл, который присваивает значения параметров значениям полей и выполняет процедуру. Получаеться примерно так:
Код

procedure TForm1.Button1Click(Sender: TObject);
var
   i : Integer;
begin
   while not Table1.Eof do
   begin
      // цикл ищет и присваивает параметры хранимой процедуре
      // по идетничным названиям полей Table1
      for i := 0 to Table1.Fields.Count - 1 do
      begin
         IBSP.Params.ParamByName( Table1.Fields.Fields[i].FieldName ).Value :=
            Table1.Fields.Fields[i].Value;
      end;
      // выполняем процедуру
      IBSP.ExecProc;
      // следующая запись
      Table1.Next;
   end;
end;

вопрос в следующем как сделать процесс такой "закачки" отдельным потоком т.к. в DBF-файле 2 млн записей? ну чтоб пользователя можно было поразвлекать выводом процесса закачки

Автор: uranpro 28.4.2009, 15:26
Код

  BeginThread(nil,0,@ProcedureName ,nil,0,PLongWord(nil)^);

Автор: uranpro 28.4.2009, 15:52
гы) можно так еще:
Код

procedure TForm1.Button1Click(Sender: TObject);
var
   i : Integer;
begin
   while not Table1.Eof do
   begin

      PB.Position++; // !
      Application.ProcessMessages; // !

      // цикл ищет и присваивает параметры хранимой процедуре
      // по идетничным названиям полей Table1
      for i := 0 to Table1.Fields.Count - 1 do
      begin
         IBSP.Params.ParamByName( Table1.Fields.Fields[i].FieldName ).Value :=
            Table1.Fields.Fields[i].Value;
      end;
      // выполняем процедуру
      IBSP.ExecProc;
      // следующая запись
      Table1.Next;
   end;
end;

Автор: rOOxus 29.4.2009, 08:37
Вариант с  BeginThread вызывает ошибку Error reading data from the connection если запустить еще одну, естественно не связанную с компонентом IBSP, транзакцию этой же программы, а если запустить еще одну копию программы, то все нормально. С Application.ProcessMessages такой ошибки вроде не возникает. Время выполнения обоих вариантов при прочих равных условиях одно и то же.
хотелось бы услышать мнение как корректнее это выполнять через BeginThread или путем проталкивания очереди сообщений Application.ProcessMessages?

Автор: Frees 29.4.2009, 08:46
Цитата(rOOxus @  29.4.2009,  10:37 Найти цитируемый пост)
хотелось бы услышать мнение как корректнее это выполнять через BeginThread или путем проталкивания очереди сообщений Application.ProcessMessages?

мне кажется это зависит от религиозных убеждении

только в случае с ProcessMessages нужно дополнительно обработать возможность закрытия программы

можно еще что то типа TProgressDialog использовать http://www.torry.net/pages.php?id=84


Автор: uranpro 29.4.2009, 10:33
попробуй создать поток так:
Код

  TMyThread = class(TThread)
  private
    i:integer;
    procedure WriteToLabel;
  protected
    procedure Execute; override;
  end;

var
  Form1: TForm1;
  MyThread:TMyThread;

implementation

{$R *.dfm}

procedure TMyThread.WriteToLabel;
begin
  Form1.Label1.Caption:=inttostr(i);
end;

procedure TMyThread.Execute;
var
  k,j:integer;
begin
  j:=1;
  for k:=1 to 1000000 do begin
    inc(j);
    if j=100 then begin
      i:=k;
      Synchronize(WriteToLabel);
      j:=1;
      end;
    end;
  Terminate;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MyThread:=TMyThread.Create(true);
  MyThread.FreeOnTerminate:=true;
  MyThread.Resume;
end;


Добавлено через 1 минуту и 36 секунд
только добавь в поток соединения и тд...

Автор: uranpro 29.4.2009, 10:51
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_10082098.html

Автор: rOOxus 29.4.2009, 16:21
спасибо огомное за помощь. у меня еще вопросик слегка не в тему:
вот код
Код

   try
      IBSP.ExecProc;
   except
      BatchResultCode := -1;
      Break;
   end;

а как мне получить текст сообщения сервера об ошибке выполнения хранимой процедуры тот самый который выкатился бы без try ... except?

Автор: uranpro 29.4.2009, 16:43
Код

try
  code
except
  on E:Exception do showmessage(E.Message);
  end;
...
try
  code
except
  on E:Exception do begin
    showmessage(E.Message);
    code;
    end;
  end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)