Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.05.03;
Скачать: [xml.tar.bz2];

Вниз

Использование крит.секции   Найти похожие ветки 

 
T2k   (2009-03-18 15:05) [0]

Есть некоторый класс. Когда я вызываю некоторый метод этого класса, то создается дополнительный поток.
Этот поток работает с девайсом (считывает с него данные). По окончанию обмена я должен передать данные главной форме для сохранения в БД и завершить поток.
Так вот...предположим, что работает сразу несколько доп.потоков (считывают данные) и когда они завершаться я не могу знать. То ли одновременно , то ли по очереди.
Вопрос в следующем, нужна ли критическая секция в главной форме ? По коду,надеюсь, понятней будет


unit Unit1;
...
Obj:=TDial.Create;
Obj.OnData:=ModemData;

...
procedure TForm1.ModemData(CashID,Mode,TaskID,Res: DWord; ThreadObj: TObjectList);
begin
  EnterCriticalSection(CS); // ???
 // сохраняю данные в БД
  LeaveCriticalSection(CS); // ???
end;

unit DialUnit;

type
 TOnData  = procedure(CashID,Mode,TaskID,Res:DWord;ThreadObj:TObjectList) of object;

type
 TDial = class(TObject)
private
 FOnData:TOnData;
 ...
public
  procedure DoData(CashID,Mode,TaskID,Res:DWord;ThreadObj:TObjectList);
end;

procedure TDial.DoData(CashID,Mode,TaskID,Res: DWord; ThreadObj: TObjectList);
begin
 if Assigned(FOnData) then OnData(CashID,Mode,TaskID,Res,ThreadObj);
end;

//доп.поток
function TDial.FDeviceThread(...)
begin
 // получаю данные с девайса
  DoData(CashID,Mode,TaskID,Y,Obj); // выгрузить данные в главн.форму
end;



 
clickmaker ©   (2009-03-18 15:49) [1]

> данные главной форме для сохранения в БД

а зачем передавать именно форме?
она еще и отображением их по ходу занимается?


 
Сергей М. ©   (2009-03-18 16:08) [2]

Решение зависит от того, что скрывается за

> // сохраняю данные в БД


 
T2k   (2009-03-18 17:17) [3]

2 clickmaker ©   (18.03.09 15:49) [1]

Ну...не знаю. Я так сам решил. Ибо не знаю, как работать с БД из потока.
Мне проще с компонентами работать при работе с БД.

>она еще и отображением их по ходу занимается?
Нет. Только сохранение в БД и все. Отображение на другой программе.

2 Сергей М. ©   (18.03.09 16:08) [2]
> Решение зависит от того, что скрывается за

FireBird. Запись данных в пару таблиц. Код показать ?
Ну вот, например основной кусок :

...
ObjList.Clear;
   for I:=0 to ThreadObj.Count-1 do
   begin
     ObjList.Add(TStringList.Create);
     TStrings(ObjList.Items[I]).AddStrings(TStrings(ThreadObj.Items[I]));
   end;
   //
   Transact;
   IBSQL1.Close;
   IBSQL1.SQL.Clear;
   case Mode of
     0:begin   // товары
         IBSQL1.SQL.Add("DELETE FROM PLUREAD WHERE CASHID=:ID");
         IBSQL1.ParamByName("ID").AsInt64:=CashID;
         IBSQL1.ExecQuery;
       end;
     1:begin  // за день
         IBSQL1.SQL.Add("DELETE FROM DAYSALES WHERE CASHID=:ID AND DAYSALE=:DAY");
         IBSQL1.ParamByName("ID").AsInt64:=CashID;
         IBSQL1.ParamByName("DAY").AsDate:=Now;
         IBSQL1.ExecQuery;
       end;
     2:begin // с накоплением
         IBSQL1.SQL.Add("DELETE FROM DAYSALESTIME WHERE CASHID=:ID AND DAYSALE=:DAY");
         IBSQL1.ParamByName("ID").AsInt64:=CashID;
         IBSQL1.ParamByName("DAY").AsDate:=Now;
         IBSQL1.ExecQuery;
       end;
     3:begin  // нулевые остатки
         IBSQL1.SQL.Add("DELETE FROM ZEROPLU WHERE CASHID=:ID");
         IBSQL1.ParamByName("ID").AsInt64:=CashID;
         IBSQL1.ExecQuery;
       end;
     6:begin // начало/конец раб.дня
         if TStrings(ObjList.Items[0]).Count>0 then
         begin
           Memo1.Lines.Add("");
           Memo1.Lines.Add("Начало рабочего дня: "+TStrings(ObjList.Items[0]).Strings[0]);
           Memo1.Lines.Add("Конец рабочего дня: "+TStrings(ObjList.Items[0]).Strings[1]);
           Memo1.Lines.Add("");
         end;
       end;
     4:begin //запись
         if ObjList.Count>0 then
         begin
           for I:=0 to TStrings(ObjList.Items[0]).Count-1 do
           begin
             if TStrings(ObjList.Items[7]).Strings[I]="0" then
             begin
               if TryStrToInt(TStrings(ObjList.Items[8]).Strings[I],hInt) then
               begin
                 IBSQL1.Close;
                 IBSQL1.SQL.Clear;
                 IBSQL1.SQL.Add("DELETE FROM PLUWRITE WHERE ID=:HID");
                 IBSQL1.ParamByName("HID").AsInteger:=hInt;
                 IBSQL1.ExecQuery;
               end;
             end else
             begin
               if TryStrToInt(TStrings(ObjList.Items[8]).Strings[I],hInt) then
               begin
                 IBSQL1.Close;
                 IBSQL1.SQL.Clear;
                 IBSQL1.SQL.Add("UPDATE PLUWRITE SET TEXTERROR=:HTEXT WHERE ID=:HID");
                 IBSQL1.ParamByName("HID").AsInteger:=hInt;
                 if TryStrToInt(TStrings(ObjList.Items[7]).Strings[I],hTemp) then
                  IBSQL1.ParamByName("HTEXT").AsString:=GetDeviceError(hTemp) else
                   IBSQL1.ParamByName("HTEXT").AsString:="глобальная ошибка";
                 IBSQL1.ExecQuery;
               end;
             end;  
           end;
         end;
       end;

   end; // end case
   TransactCommit;
   Transact;
   //
   //SaveLog(" First Transact  Касса:"+IntToStr(CashID));
   // запись
   case Mode of
   1:begin // продажи за день
       for I:=0 to TStrings(ObjList.Items[0]).Count-1 do
       begin
         IBSQL1.SQL.Clear;
         //
         if STCIstokMode=0 then
         begin // обычная версия
           IBSQL1.SQL.Add("INSERT INTO DAYSALES VALUES(GEN_ID(IDDAYSALES,1),");
           IBSQL1.SQL.Add(":DAY,:CASH,:CODE,:NAME,:PRICE,:AMOUNT,:GRP,:TAX,:NSALE,:SSALE,:N PAY,:SPAY)");
         end;
         if STCIstokMode=1 then
         begin    // версия для Одессы
           IBSQL1.SQL.Add("INSERT INTO DAYSALES VALUES(GEN_ID(IDDAYSALES,1),:TASK,");
           IBSQL1.SQL.Add(":DAY,:CASH,:CODE,:NAME,:PRICE,:AMOUNT,:GRP,:TAX,:NSALE,:SSALE,:N PAY,:SPAY)");
           IBSQL1.ParamByName("TASK").AsInteger:=TaskID;
         end;
         //
         IBSQL1.ParamByName("DAY").AsDate:=Now;
         IBSQL1.ParamByName("CASH").AsInt64:=CashID;
         if not TryStrToInt64(TStrings(ObjList.Items[0]).Strings[I],hInt64) then hInt64:=0;
         IBSQL1.ParamByName("CODE").AsInt64:=hInt64;
         if Length(TStrings(ObjList.Items[1]).Strings[I])=0 then
          IBSQL1.ParamByName("NAME").Value:=null else
           begin
             hSt:= TStrings(ObjList.Items[1]).Strings[I];
             if Length(hSt)>25 then hSt:=Copy(hSt,1,25);
             IBSQL1.ParamByName("NAME").Value:=hSt;
           end;
         if not TryStrToFloat(TStrings(ObjList.Items[2]).Strings[I],hExt) then hExt:=0;
         IBSQL1.ParamByName("PRICE").AsFloat:=hExt;
         if not TryStrToFloat(TStrings(ObjList.Items[3]).Strings[I],hExt) then hExt:=0;
         IBSQL1.ParamByName("AMOUNT").AsFloat:=hExt;
         if not TryStrToInt(TStrings(ObjList.Items[6]).Strings[I],hInt) then hInt:=0;
         IBSQL1.ParamByName("GRP").AsInteger:=hInt;
         if not TryStrToInt(TStrings(ObjList.Items[7]).Strings[I],hInt) then hInt:=0;
         IBSQL1.ParamByName("TAX").AsInteger:=hInt;
         if not TryStrToFloat(TStrings(ObjList.Items[4]).Strings[I],hExt) then hExt:=0;
         IBSQL1.ParamByName("NSALE").AsFloat:=hExt;
         if not TryStrToFloat(TStrings(ObjList.Items[5]).Strings[I],hExt) then hExt:=0;
         IBSQL1.ParamByName("SSALE").AsFloat:=hExt;
         if not TryStrToFloat(TStrings(ObjList.Items[8]).Strings[I],hExt) then hExt:=0;
         IBSQL1.ParamByName("NPAY").AsFloat:=hExt;
         if not TryStrToFloat(TStrings(ObjList.Items[9]).Strings[I],hExt) then hExt:=0;
         IBSQL1.ParamByName("SPAY").AsFloat:=hExt;
         //
         IBSQL1.ExecQuery;
       end;
     end;



 
clickmaker ©   (2009-03-18 17:22) [4]

> [3] T2k   (18.03.09 17:17)
> 2 clickmaker ©   (18.03.09 15:49) [1]
>
> Ну...не знаю. Я так сам решил. Ибо не знаю, как работать
> с БД из потока.
> Мне проще с компонентами работать при работе с БД.

используй DataModule тогда


 
Сергей М. ©   (2009-03-18 17:24) [5]


> T2k   (18.03.09 17:17) [3]


FB требует как минимум отдельное соединение (отдельный объект TIBDatabase) на каждый тред, использующий это соединение для последующего доступа к объектам БД.

Этот требование тобой, похоже, не выполняется, так что дальнейший разговор про КС пока лишен смысла


 
T2k   (2009-03-18 17:34) [6]

2 Сергей М. ©   (18.03.09 17:24) [5]
FB требует как минимум отдельное соединение (отдельный объект TIBDatabase) на каждый тред, использующий это соединение для последующего доступа к объектам БД.

Погодите...У меня все доп.потоки передают данные главному. А из главного я и работаю с БД. Повторюсь...главные поток(читай Unit1.pas) работает c БД. Что не так ?

2 clickmaker ©   (18.03.09 17:22) [4]
> используй DataModule тогда

Хорошо. Я посмотрю в эту сторону. Но а чем мой вариант плох ???


 
Сергей М. ©   (2009-03-18 17:36) [7]


> У меня все доп.потоки передают данные главному


Где это видно из приведенного кода ?
Я этого не вижу, приведи цитату ..


 
T2k   (2009-03-18 17:40) [8]

2 Сергей М. ©   (18.03.09 17:36) [7]

Ну как в [0].
Работает доп.поток, накапливает данные в TObjectList. Далее вызывается событие  DoData, код которого расположен в unit1.pas. Разве я не прав ?


 
Сергей М. ©   (2009-03-18 17:58) [9]


> Далее вызывается событие  DoData, код которого расположен
> в unit1.pas


Так ведь в unit1 расположен код, а не кодовый поток (тред) !

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

В дан.случае тело проц-ры DoData будет исполнено в том же потоке, в котором эта процедура была вызвана.


 
clickmaker ©   (2009-03-18 18:19) [10]

> [6] T2k   (18.03.09 17:34)
>
> 2 clickmaker ©   (18.03.09 17:22) [4]
> > используй DataModule тогда
>
> Хорошо. Я посмотрю в эту сторону. Но а чем мой вариант плох
> ???

во-первых, при наличии большого числа компонентов БД на форме, ты в один прекрасный момент не сможешь раскопать визуальные, которые окажутся под ними.
ну а во-вторых - нормальное и логичное желание отделять работу с БД от интерфейса. Это не кажется актуальным, когда у тебя 2-3 эдита и один кверик, но на более серьезном проекте преимущества будут налицо, поверь


 
T2k   (2009-03-18 18:44) [11]

2 Сергей М. ©   (18.03.09 17:58) [9]

Спасибо. Теперь вроде понятно. Только опять таки вопрос...как правильно подойти к моей задаче ? Прямо из доп.потока сохранять данные в БД или как-то (сообщением или еще как) отправить данные из доп.потока главному и там(в главном) сохранять ?

2  clickmaker ©   (18.03.09 18:19) [10]

Спасибо, понял. Вот бы еще примерчик...как из потока работать с БД ;)
Хотя поищу...может что в инете есть.


 
Сергей М. ©   (2009-03-18 20:30) [12]


> Прямо из доп.потока сохранять данные в БД


> или как-то (сообщением или еще как) отправить данные из
> доп.потока главному и там(в главном) сохранять ?


Оба варианта имеют право на жизнь, выбирать тебе.
Хочу лишь заметить, что второй вариант - это как раз то что ты хотел добиться с пом. КС в изначальном вопросе.



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

Форум: "Начинающим";
Текущий архив: 2009.05.03;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.007 c
6-1202735762
gear
2008-02-11 16:16
2009.05.03
Как выключить HTTP/1.1 и включить HTTP/1.0 в WININET?


15-1236093100
boa_kaa
2009-03-03 18:11
2009.05.03
Те, кто ждал - дождались...


2-1237488796
Yuriy
2009-03-19 21:53
2009.05.03
Рамочка TsMonthCalendar (AlphaControls)


2-1237207156
madmech
2009-03-16 15:39
2009.05.03
Как рисовать на канве BitBtn?


2-1237842664
alexander-rsh
2009-03-24 00:11
2009.05.03
Удаление папки





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский