在Delphi2006编写一个简单的DCOM分布式应用程序所遇到的问题。(50分)

  • 主题发起人 主题发起人 awfigsk
  • 开始时间 开始时间
A

awfigsk

Unregistered / Unconfirmed
GUEST, unregistred user!
服务器端的二个单代码:
====主窗口
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
private
{ Private declarations }
nClientCount:integer;
public
{ Public declarations }
procedure UpdateClientNum(i:integer);
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.UpdateClientNum(i: integer);
begin
nclientCount:=nClientCount+i;
[red]Label2.Caption:='客户数:'+IntToStr(nClientCount);[/red]
//当我改成Label1.caption:=...时,当客户端一运行,服务器端就会死机,并且客户端
//也无法正常运行。
end;

end.

======远程数据模块
unit Unit2;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
Windows, Messages, SysUtils, Classes, ComServ, ComObj, VCLCom, DataBkr,
DBClient, Project1_TLB, StdVcl, DB, ADODB, Provider;
type
TMyFirstDCOMServer = class(TRemoteDataModule, IMyFirstDCOMServer)
DataSetProvider1: TDataSetProvider;
ADOConnection1: TADOConnection;
ADOTable1: TADOTable;
procedure RemoteDataModuleCreate(Sender: TObject);
procedure RemoteDataModuleDestroy(Sender: TObject);
private
{ Private declarations }
protected
class procedure UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
override;
public
{ Public declarations }
end;

implementation
{$R *.DFM}
uses unit1;
class procedure TMyFirstDCOMServer.UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string);
begin
if Register then
begin
inherited UpdateRegistry(Register, ClassID, ProgID);
EnableSocketTransport(ClassID);
EnableWebTransport(ClassID);
end else
begin
DisableSocketTransport(ClassID);
DisableWebTransport(ClassID);
inherited UpdateRegistry(Register, ClassID, ProgID);
end;
end;

[red]procedure TMyFirstDCOMServer.RemoteDataModuleCreate(Sender: TObject);
begin
Form1.UpdateClientNum(1);
end;

procedure TMyFirstDCOMServer.RemoteDataModuleDestroy(Sender: TObject);
begin
Form1.UpdateClientNum(-1);
end;
[/red]
//当主窗口UpdateClientNum方法中的代码Label2改成Label1后,程序运行
//RemoteDataModuleCreate方法中Form1.updateClientNum(-1)就停止不运行了。
//我跟踪看了一下,发现是停在主窗口UpdateClientNum方法中的Label1.caption...赋值
//这一语句上面。
initialization
TComponentFactory.Create(ComServer, TMyFirstDCOMServer,
Class_MyFirstDCOMServer, ciMultiInstance, tmApartment);
end.

客户端程序代码:
====客户端主窗口代码:
unit Client;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, DBCtrls, Grids, DBGrids, StdCtrls;
type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
uses ClientDM;
procedure TForm1.Button1Click(Sender: TObject);
begin
DataModule2.ClientDataSet1.Active:=True;
end;

end.
====客户端数据模块代码:
unit ClientDM;
interface
uses
SysUtils, Classes, DB, DBClient, MConnect;
type
TDataModule2 = class(TDataModule)
DCOMConnection1: TDCOMConnection;
DataSource1: TDataSource;
ClientDataSet1: TClientDataSet;
private
{ Private declarations }
public
{ Public declarations }
end;

var
DataModule2: TDataModule2;
implementation
{$R *.dfm}
end.

以上代码在Delphi7中运行很正常,将UpdateClientNum方法中Label2改成label1也能正常运行。但在Delphi2006中就发生死机了。不知哪位高手能指点一下是程序中哪里有问题?谢谢!
 
将 Label2.AutoSize := False;
将TDataModule放在多层系统的多线程中应考虑线程安全问题。
 
大侠,太感谢您的回答了,的确是您讲的这种情况。
但这真让我有点困惑了,就像上面这个DCOM应用程序,在多线程中还要考虑到哪些情况呢?
不知您是否还能指点一下?谢谢!
 
帮顶!
╭=========================================╮
80G海量源代码,控件,书籍全免费狂下不停!
http://www.source520.com

╰=========================================╯
 
建议你使用SendMessage的方法,向窗口发消息。然后在Form里面定义一个
Procedure XXX(msg: TMessage) message 10001;
就可以了。
 
多人接受答案了。
 

Similar threads

后退
顶部