Конференция "Corba" » "Out of memory" и ClientDataSet.Data [Delphi, Windows]
 
  • yuray (15.01.08 17:24) [0]
    Сервер реализован как сервис (точная копия примера Набережных С.)
    Добавил туда (бросил прямо на dfm-ку сервиса) компоненты IBDatabase1, IBTransaction1, IBQuery1, DataSetProvider1. Добавил метод

    procedure TSvcComObj.Data(out d: OleVariant);
    begin
     ComService.IBQuery1.Open;
     d:=ComService.DataSetProvider1.Data;
     ComService.IBQuery1.Close
    end;

    ...и все. Сервер готов.

    Клиент.

    На форму бросил DBGrid1, DataSource1 и ClientDataSet1.
    Жму на кнопку...

    procedure TForm1.Button1Click(Sender: TObject);
    var
     Svc: ISvcComObj;
     d:Olevariant;
    begin
     Svc:=CoSvcComObj.Create;
     Svc.Data(d); ///////////////////// тут все виснет
     ClientDataSet1.Data:=d;
    end;

    ...и (если данных много) получаю EOleException "Out of memory".
    Что не так?
  • Сергей М. © (16.01.08 08:33) [1]

    > Что не так?


    Не хватило виртуальной памяти.

    Либо отказывайся от выбранной логики либо передавай/принимай сжатые данные
  • yuray (16.01.08 10:11) [2]
    Спасибо за ответ.
  • ага (16.01.08 12:50) [3]
    А как поведет себя IBQuery, если его и все связанные компоненты создавать в одном потоке, а IBQuery1.Open вызывать в другом? Я просто не в курсе. Прсосто для провеки попробуй добавить в сервер еще один DataModule без AutoCreate, перекидай на него все DB-компоненты, и создавай его вручную в том потоке, из которого будешь вызывать Open. Можно типа так

    TComService = class...
    private
     FMyDataModule: TMyDataModule;
    public
     property MyDataModule: TMyDataMopdule read FMyDataModule write FFMyDataModule;

    procedure TSvcComObj.Data(out d: OleVariant);
    begin
    if ComService.MyDataModule = nil then ComService.MyDataModule:= TMyDataModule.Create(nil);
    with ComService.MyDataModule do
     begin
      IBQuery1.Open;
      d:= DataSetProvider1.Data;
      IBQuery1.Close;
    end;
    end;


    Ну и удалить не забудь при завершении потока.
  • Сергей М. © (16.01.08 14:21) [4]

    > ага   (16.01.08 12:50) [3]


    Потоки-то тут причем ?
  • yuray (16.01.08 15:58) [5]
    Да, действительно ничего не изменилось...
  • ага (16.01.08 16:13) [6]

    > Сергей М. ©   (16.01.08 14:21) [4]


    > Потоки-то тут причем ?

    Чисто воды гипотеза:)) Я ж сказал - не в курсе, можно ли так работать с IBxxx.
  • Сергей М. © (17.01.08 10:32) [7]

    > не в курсе, можно ли так работать с IBxxx


    Нельзя.
    Но Out of memory возникает по совершенно иной причине.
  • yuray (17.01.08 11:57) [8]
    > Сергей М. ©   (17.01.08 10:32) [7]
    > Нельзя.

    Почему так работать нельзя?

    Первый раз пишу сервис и второй раз СОМ-объект. Пример Набережных С. демонстрирует создание двух типов объектов - обычного и синглетона. Подскажите, какой тип объекта мне нужно использовать, если по условию задания с базой будет работать 1 пользователь? Спасибо.
  • Сергей М. © (17.01.08 12:26) [9]

    > yuray   (17.01.08 11:57) [8]


    > Почему так работать нельзя?


    Потому что клиентская часть СУБД IB не потокобезопасна.

    Иными словами, нельзя использовать коннект к базе (IBDatabase), созданный в одном потоке, в запросах (IBQuery), созданных в других потоках.
  • yuray (17.01.08 13:29) [10]
    А какой тип объекта выбрать: обычный или синглетон? Где об этом можно подробно почитать?
  • Сергей М. © (18.01.08 15:16) [11]

    > Где об этом можно подробно почитать?
    >


    У Эрика Хармона, например.
  • ага (18.01.08 18:38) [12]

    > А какой тип объекта выбрать: обычный или синглетон?

    А какой надо-то? Хошь, чтобы все клиенты подключались к одному объекту - выбирай синглетон. Хошь, чтоб для каждого клиента создавался отдельный объект - не выбирай синглетон:)
  • yuray (21.01.08 12:46) [13]
    Спасибо за ответы
 
Конференция "Corba" » "Out of memory" и ClientDataSet.Data [Delphi, Windows]
Есть новые Нет новых   [120350   +22][b:0][p:0.001]