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

Вниз

многопоточность и COM   Найти похожие ветки 

 
vlad_ri   (2005-04-28 18:23) [0]

Наставьте на путь истинный :)

В приложении из дополнительного потока надо выполнить функцию на Application Server-e. В качестве Application Server-а выступает объект унаследованный от TMtsDataModule, подключение через TSocketConnection, интерфейс AppServer-а получаю следующим способом:
iSrvr := ITTestCOMThreadDisp(IDispatch(SocketConnection1.AppServer));

В интерфесе AppServer-а релизована и вызываеться всеголишь один метод.
При вызове из основного потока приложения всё выполняеться без ошибок, при выполнении из дополнительного метод выполняеться но при завершении выдаются исключения  EVariantInvalidArgError with message "Invalid argument" и ESocketConnectionError with message "Error reading from socket"

Вот реализация вызываемого метода:

procedure TTTestCOMThread.Test(const AString: WideString;
 Itterations: Integer; out Finished: WordBool);
var i: integer;
   tf: TextFile;
begin
 Finished := False;
 AssignFile(tf,"f:\test.txt");
 ReWrite(tf);
 i := 1;
 while i <= Itterations do
 begin
   writeln(tf,i,#9,AString);
   inc(i);
 end;
 CloseFile(tf);
 Finished := true;
end;


и реализация клиента


program Project1;

uses
 Forms,
 ComObj,
 ActiveX,
 Unit1 in "Unit1.pas" {Form1},
 TestComThread_TLB in "..\Server\TestComThread_TLB.pas";

{$R *.res}

begin
 CoInitFlags := COINIT_MULTITHREADED;
 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 Application.Run;
end.

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, TestComThread_TLB, DB, DBClient, MConnect, SConnect, StdCtrls;

type
 TForm1 = class(TForm)
   SocketConnection1: TSocketConnection;
   Button1: TButton;
   Edit1: TEdit;
   procedure FormCreate(Sender: TObject);
   procedure Button1Click(Sender: TObject);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
 private
   { Private declarations }
   iSrvr: ITTestCOMThreadDisp;
 public
   { Public declarations }
 end;

 TMyThread = class(TThread)
 protected
   procedure Execute; override;
 public
   iSrvr: ITTestCOMThreadDisp;
   IterCount: integer;
   procedure GetIterCount;
   constructor Create(Intrfc: ITTestCOMThreadDisp);
   destructor Destroy; override;
 end;

var
 Form1: TForm1;

implementation

uses ComObj, ActiveX;

{$R *.dfm}

constructor TMyThread.Create(Intrfc: ITTestCOMThreadDisp);
begin
 FreeOnTerminate := true;
 iSrvr := Intrfc;
 inherited Create(false);
end;

procedure TMyThread.GetIterCount;
begin
 IterCount := StrToInt(Form1.Edit1.Text);
end;

procedure TMyThread.Execute;
var stopped: WordBool;
begin
 Synchronize(GetIterCount);
 CoInitializeEx(nil, COINIT_MULTITHREADED);

 iSrvr.Test("Salut!!!",IterCount,stopped);

 CoUninitialize;
end;

destructor TMyThread.Destroy;
begin
 iSrvr := nil;
 inherited;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 SocketConnection1.Open;
 if SocketConnection1.Connected then
   iSrvr := ITTestCOMThreadDisp(IDispatch(SocketConnection1.AppServer));
end;

procedure TForm1.Button1Click(Sender: TObject);
var stopped: WordBool;
   tt: TTime;
   mt: TMyThread;
begin
//  tt := Now;
//  iSrvr.Test("Salut!!!",StrToInt(Edit1.Text),stopped);
//  if stopped then
//    ShowMessage(TimeToStr(Now-tt));
 mt := TMyThread.Create(iSrvr);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 iSrvr := nil;
 SocketConnection1.Close;
end;

end.


P.S.: Ногами не бить :)


 
Набережных С. ©   (2005-04-29 14:37) [1]

Тут дело не в СОМ, а в особенностях реализации TSocketConnection, не дружит он с многопоточностью на клиенте. Обмен с сервером он ведет в дополнительном потоке, а тот при приеме ответа от сервера переправляет его сообщением окну, созданному SocketConnection. А так как это окно создается в основном потоке, то и ответ придет туда, а не в тот поток, который вызвал метод. Если правильно помню, должна помочь установка SupportCallbacks в false. Но я бы не советовал, все равно там с потокобезопасностью не все ладно, насколько помню. Еще можно отказаться от MTA и маршалировать интерфейс в апартамент дополнительного потока, но смысл в этом нулевой - все равно вызов метода будет маршалирован в основной поток и в нем будет ждать ответа - окажутся заблокированы и главный, и дополнительный потоки, пока сервер не обработает метод. В общем, резюме такое: при работе через SocketConnection многопоточность использовать не стоит.


 
vlad_ri   (2005-04-29 16:12) [2]

Да действительно, вы оказались совершенно правы...

Замена на TDCOMConnection решила проблему.

Но раз уж вы упоминали о Callback, у меня появился встречный вопрос - как реализовывается Callback через TDCOMConnection?


 
Набережных С. ©   (2005-05-03 14:12) [3]


> vlad_ri   (29.04.05 16:12) [2]

При работе через DCOM работа идет через стандартные механизмы COM, дополнительно ничего не требуется.



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

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

Наверх





Память: 0.47 MB
Время: 0.014 c
15-1140346770
QwertyKz
2006-02-19 13:59
2006.03.12
Автоматизация библиотек


3-1137241298
vol
2006-01-14 15:21
2006.03.12
Как установить нужную кодировку MySql в Дулфи


4-1135254446
Dush
2005-12-22 15:27
2006.03.12
Постоянно слушать Com-порт


2-1140863417
Volfram
2006-02-25 13:30
2006.03.12
Microsoft Help Workshop


15-1140406651
никак не получается
2006-02-20 06:37
2006.03.12
таблицы





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский