Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

how can I make my remote data module support multiple thread?

Posted on 2001-07-25
13
Medium Priority
?
850 Views
Last Modified: 2010-04-06
in delphi5 I create remote app server using Apartment thread module,
in my remote app server have a simple method 'myfunc',it only delay some time.
in my client application i make a thread object  'TMyThread',it call remote server's 'myfunc'
i want the remote app server's method exec in multiple thread.
for example in my client application,i make three thread T1,T2,T3,T1 delay 1 second,
T2 delay 2 second,T3 delay 3 second,i want total cost is 3 second,but now it is 6 second.
how can i make it total cost 3 second.


following is my client application code.

unit mythread;

interface

uses
  Classes, Graphics, ExtCtrls,mconnect,stdctrls,Sysutils,Db,
  DBClient,Windows,sconnect,comobj,ActiveX;

type

  TMyThread=class(TThread)
  private
    Foconnect:TCustomConnection;
    FsResult:String;
    FiSecond:integer;
  protected
    procedure Execute; override;
    procedure dofunc;
  public
    constructor Create(poconnect:TCustomConnection;piSecond:Integer);
  end;


implementation


constructor TMyThread.Create
  (poDcom:TCustomConnection;piSecond:Integer);
begin
  Foconnect :=poconnect;
  FoMemo:=poMemo;
  FiSecond:=piSecond;
  freeOnTerminate:=False;
  inherited Create(False);
end;

procedure TMyThread.dofunc;
var
  sResult:variant;
begin
  (Foconnect as TSocketConnection).AppServer.myfunc(FiSecond,sResult);
  FsResult:=sResult+'FiSecond is'+IntToStr(FiSecond);
end;

procedure TMyThread.Execute;
begin
  ...
  ...
  Synchronize(dofunc);
  ...
  ...
end;

end.


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, DBClient, MConnect, StdCtrls, Spin, ExtCtrls, SConnect;

type
  TForm1 = class(TForm)
    Button1: TButton;
    txt2: TSpinEdit;
    Label1: TLabel;
    Label2: TLabel;
    txt3: TMemo;
    SocketConnection1: TSocketConnection;
    SocketConnection2: TSocketConnection;
    SocketConnection3: TSocketConnection;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses mythread;

{$R *.DFM}


var
  intseconds:integer;
  ThreadRuning:integer;
  istart,iend:integer;
  idelay:double;
  T1,T2,T3:TMyThread;


procedure TForm1.Button1Click(Sender: TObject);
begin
  intseconds:=StrToInt(txt2.Text);
  SocketConnection1.Connected:=True;
  SocketConnection2.Connected:=True;
  SocketConnection3.Connected:=True;
  ThreadRuning:=3;
  T1:=TMyThread.create(SocketConnection1,intseconds);
  T2:=TMyThread.create(SocketConnection2,intseconds*2);
  T3:=TMyThread.create(SocketConnection3,intseconds*3);
  {
    I want T1,T2,T3 exec simultaneity,but now it is T1  
    finish, then T2 run, T2 finish then T3 run
  }
end;

end.
0
Comment
Question by:bluestar
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
13 Comments
 
LVL 2

Expert Comment

by:Felixin
ID: 6317541
Make sure that in the Initialization part of your remote data module you have a call to

TComponentFactory.Create

with the Instancing Call set to ciMultiInstance.
0
 

Author Comment

by:bluestar
ID: 6320629
to Felixin,I am sure i have do this,fllowing is code,but it  still can not work like i want it is

initialization
  TComponentFactory.Create(ComServer, TAMServer,
    Class_AMServer, ciMultiInstance, tmApartment);

0
 
LVL 2

Expert Comment

by:SChertkov
ID: 6321872
I think you client code is incorrect.
The fact that dofunc on the client wrap into Synchronize
call and work in main thread in any case.
Try correct you code as following

procedure TMyThread.Execute;
begin
 OleCheck(CoInitializeEx(nil, COINIT_APARTMENTTHREADED));

 dofunc; // not Synchronize !!!

 ...
 ...
end;

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:bluestar
ID: 6325480
thank SChertkov,but when i call remote app server's method
from thread (not Synchronize ) it always raise exception. i must create TSocketConnection in the thread ? can you show me some sample code how to call remote app server's method in the thread.
0
 

Author Comment

by:bluestar
ID: 6325486
thank SChertkov,but when i call remote app server's method
from thread (not Synchronize ) it always raise exception. i must create TSocketConnection in the thread ? can you show me some sample code how to call remote app server's method in the thread.
0
 
LVL 2

Expert Comment

by:SChertkov
ID: 6325589
That exception raised ?
You shure that initialize OLE in this thread
(OleCheck(CoInitializeEx(nil, COINIT_APARTMENTTHREADED)) ?
0
 
LVL 2

Expert Comment

by:SChertkov
ID: 6325619
I see sconnect.pas more carefully and ascertain that
TSocketConnection can work only in main thread or
may be in thread that have message queue.

You can try create thread with message queue,
but i am not sure that TSocketConnection will be
normal work.

0
 
LVL 2

Expert Comment

by:SChertkov
ID: 6325624
For do this, also you must create and use TSocketConnection in TThread.Execute body.
0
 
LVL 2

Expert Comment

by:SChertkov
ID: 6325679
It's work !
Try following code:


const
  CM_INIT = WM_USER + 101;

type
  TSocketThread = class(TThread)
  private
    Handle: Cardinal;
    SocketConnection: TSocketConnection;
    sResult: OleVariant;
    procedure WndProc(var Message: TMessage);
  protected
    procedure Execute; override;
  end;


procedure TSocketThread.WndProc(var Message: TMessage);
begin
  if Message.Msg = CM_INIT then
    begin
      SocketConnection.Host := 'localhost';
      SocketConnection.Port := 211;
      SocketConnection.ServerName := 'Project1.abc';
      SocketConnection.Connected := True;
      sResult := SocketConnection.AppServer.myfunc(100);
      SocketConnection.Close;
      Terminate;
    end;
end;

procedure TSocketThread.Execute;
var
  msg: TMsg;
begin
  OleCheck(CoInitializeEx(nil, COINIT_APARTMENTTHREADED));
  SocketConnection := TSocketConnection.Create(nil);
  Handle := AllocateHWnd(WndProc);
  try
    PostMessage(Handle, CM_INIT, 0, 0);
    while GetMessage(msg, 0, 0, 0) and not Terminated do
      DispatchMessage(msg);
  finally
    DeallocateHWnd(Handle);
    SocketConnection.Free;
  end;
end;

procedure TForm3.Button1Click(Sender: TObject);
var
  SocketThread: TSocketThread;
begin
  SocketThread := TSocketThread.Create(True);
  SocketThread.FreeOnTerminate := True;
  SocketThread.Resume;
end;
0
 

Author Comment

by:bluestar
ID: 6336917
very thank SChertkov answer my question,but i can not compile you code,error message is undeclared identifier 'AllocateHWnd',undeclared identifier 'DeallocateHWnd'. where the function 'AllocateHWnd' and 'DeallocateHWnd' are declared?please tell me. thank again
0
 
LVL 2

Expert Comment

by:SChertkov
ID: 6343355
unit Forms...
0
 

Author Comment

by:bluestar
ID: 6348123
thank SChertkov ,you code real work,but i find a new problem OnTerminate event can not be trrige! why?
0
 
LVL 2

Accepted Solution

by:
SChertkov earned 900 total points
ID: 6348340
Because i mistake, you need correct:
while not Terminated and GetMessage(msg, 0, 0, 0) do :)

Also, i think in you case you can try more simple:

procedure TSocketThread.Execute;
begin
  SocketConnection.Host := 'localhost';
  SocketConnection.Port := 211;
  SocketConnection.ServerName := 'Project1.abc';
  SocketConnection.Connected := True;
  sResult := SocketConnection.AppServer.myfunc(100);
  SocketConnection.Close;
end;


0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
Suggested Courses

618 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question