三层次的问题:客户端有13个数据模块,服务器端也有13个程序与之对应,出现内存错误!(200分)

  • 主题发起人 主题发起人 tomol
  • 开始时间 开始时间
to tomol:
不好意思,理解错了。--以为是多模块共享应用服务器的连接问题呢~~
你的"标准备代码关闭"我不知道是从哪来的标准。
在窗体的OnDestroy事件里把自己置为nil这种方法在任何地方都从来未见过。
最好能把创建代码也贴出来,如果里面使用了API函数SetParent的也贴出来,一定能解决。
别外,我对f643208的意见有保留地表示赞同。
其实可以在一个应用程序服务器中使用多个RemoteDataModule来解决的。
 
各位朋友:
我现在还在测试该程序,若有新的发现一定给大家汇报,让我们共同进步,希望大家
继续关注该话题,还请高手多多指点!!
 
to all:
我发现若是客户端的TClientDataSet中有在设计期是打开的,则用BoundsChecker测试会
出现错误,所以,我建议客户端数据模块在设计期统统关闭.在运行时再动态打开.
 
不管你的程序写的怎么样,服务器开启的时候就13个连接到数据库的线程
服务器下都要被你吓死了!
 
你可以在十三台电脑上单独开那十三个应用服务器,然后在连接试试?
 
to hly:
可是,在主界面打开的时候所有的SocketConnection都关闭,仍然有错误.
btw:一般建立多少个连接为益呢??
to dingfuhai:
我们没有那么多电脑,哈哈
to all:
现在,我建立了一个新的主界面,先把我自己的一个模块加入,在98下测,仍然可能会
出现蓝屏错误,只不过出现的几率非常小,我测了近40次,出现了一次蓝屏错误(在一打开
主界面就关闭的情况下,DataModule在主Form前自动建立,connection关闭,注:DataModule
是从我们自己的基类继承,基类主要写了BeforePost,AfterPost等事件)
 
我和您遇到的问题一模一样。该内存不能读。等。还有就是多用户上来。应用层就死掉。
我问了几个朋友。他们的软件运行半年也不关服务器。
才发现一切都是自已写程序和设计程序的错。我现在已全部改完。现在没有任何错。
您最好把代码贴出来。
 
to billrobin:
能否把您解决问题的思路说一下呢?现在就是不知从何做起.多谢多谢!
我们的整个代码量太大了,无法全部贴出.您需要看哪一部分呢??
 
to all:
程序在运行时基本不会出什么错误,无论是浏览还是操作数据等
但怪就怪在一关闭程序就出错,请大侠们多多援手,小弟再次万分感谢!!
 
問一下;
單獨連server 有無 問題?
 
設計有大問題
 
一個程序連多個com server,連通了嗎?
多個程序連多個com server,連通了碼?
 
i think
one pro connect one com server ok!!!
one pro connect many com server ok ???
use object pooler.(no state or state)
 
我现在把您出错的信息发到网上,您看一下:
'Access violation at address 0043836 in module 'comserver.exe',read of
address oodf1458'.
解决问题的思路:
1:一定要取掉多余的代码。要反复检查才看到出来。
2:有一个网友说得对,服务器吓得被吓死了。有一定道理。不要用太多的远程数据模板。
3:在程序中有些公用的方法全部写到一个单元里。不要东放西放。
4:尽量少用变体类型。
5:获取远程接口的方法很多,您用的是那一种,有些不安全。我测试过。
6:在窗体关闭时,写上:action:=cafree.
。。。。
最后重要一点先全部折开,然后一个单元一个单元的组合。您在测试时,把内存加大。
我一般都在512M.意思是开二个DELPHI。一个服务器,一个客户端。测试时,服务器
不要运行可执行文件。在delphi中运行。另外一个开客户端。一个单元一个单元的组合
。如果有一个单元有BUG。应用层要跳出来。就是上面的错。我遇到过几次了。这方面还多得
很。一下子也给您说不完。最主要的是代码的安全性。要一行一行的看。您发一个有代表性
单元给我。我看一下。我就知道您的编程习惯。
最后一点,也很重要。分要给我哟!哈。。。。。
 
to dragonlee007:
各个模块单独连自己的服务器应该是没有问题,但一组合起来马上就有问题(之所以这样
说是因为:各个模块测了很多遍了,都没有问题,但所有的模块组合在一起,马上就有明显
的问题)
比如说:我做仓库管理,我有一个仓库的应用程序服务器,张三做采购,他也有一个采购的
应用程序服务器,两个服务器没有什么关联,但有一些公用的应用程序服务器,比如编码,
基本信息等,各个模块都会用到.
to billrobin:
-- 我现在把您出错的信息发到网上,您看一下:
--'Access violation at address 0043836 in module 'comserver.exe',read of
--address oodf1458'
这个出错信息您是怎样得到的??
对您提出的问题:
1.在Build All时显示的编译错误和警告基本上都清除了(多余的代码这个概念很难讲)
2.我们共有13个远程数据模块,这样是不是太多了呢?
3.我们基本上是这样做的,有好几个公用的单元,而且,我们所有的界面都是从基类继承
而来(在一个包里),所以有很多代码都是在基类写的(btw:有没有测试package的工具?)
4.用的不多(我基本不用,别人可能用到一些)
5.您所说的远程接口是指:Com或Socket吗?我们用的是Delphi的Socket连接
6.我们是ShowModal的窗口,原来是在Form的Close事件里写Action := caFree
在Destroy事件里写FormXXX:=nil;(具体见上面的讨论) 但有网友说这样不行
要在ShowModal后直接Free和:=nil,我觉得有一定的道理,您觉得呢?
 
to billrobin:
分不是问题,我还会继续加分. :)
我把一段比较短一些的代码先放上来.您先看(各个界面的代码不是很多,大量的代码在
客户端DataModule里)
unit untwmWarehouse;
interface
uses
rhQX, untBasicServices, untGet, untLanguage,
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
UNTSINGLEQE, ExtCtrls, ActnList, ImgList, Grids, DBGrids, DBCtrls,
StdCtrls, Buttons, ComCtrls, Mask, Db;
type
TfrmwmWarehouse = class(TfrmSingleQE)
Label2: TLabel;
Label4: TLabel;
Label5: TLabel;
edtWarehouseNo: TEdit;
edtWarehouseName: TEdit;
edtLocation: TEdit;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
dbeWarehouseNo: TDBEdit;
dbeWarehouseName: TDBEdit;
dbeLocation: TDBEdit;
btbPrint: TBitBtn;
edtWarehouseStatus: TEdit;
spbStatus: TSpeedButton;
dsWMWarehouse: TDataSource;
Label3: TLabel;
edtWarehouseType: TEdit;
spbWarehouseType: TSpeedButton;
Label9: TLabel;
dbeWarehouseType: TDBEdit;
spbWarehouseTypeDB: TSpeedButton;
procedure FormDestroy(Sender: TObject);
procedure dsWMWarehouseDataChange(Sender: TObject;
Field: TField);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject;
var Action: TCloseAction);
procedure btbQueryClick(Sender: TObject);
procedure spbStatusClick(Sender: TObject);
procedure DBNavigator1BeforeAction(Sender: TObject;
Button: TNavigateBtn);
procedure ClearText(Sender: TObject);
procedure spbWarehouseTypeClick(Sender: TObject);
procedure spbWarehouseTypeDBClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmwmWarehouse: TfrmwmWarehouse;
implementation
uses untwmStockInStat, untwmStockOutStat,
untwmStockStat, untWMDM;
{$R *.DFM}
procedure TfrmwmWarehouse.FormDestroy(Sender: TObject);
begin
inherited;
frmwmWarehouse := nil;
end;

procedure TfrmwmWarehouse.dsWMWarehouseDataChange(Sender: TObject;
Field: TField);
begin
inherited;
rhQx.PanelCount(Sender, pnlCount);
end;

procedure TfrmwmWarehouse.FormCreate(Sender: TObject);
begin
inherited;
DMWM.cdsWMWarehouse.Open;
end;

procedure TfrmwmWarehouse.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
inherited;
DMWM.cdsWMWarehouse.Close;
Action := caFree;
end;

procedure TfrmwmWarehouse.btbQueryClick(Sender: TObject);
var
sInitSQL, sOtherSQL: string;
begin
inherited;
sInitSQL := 'Select warehouseNo, warehouseName, location, status, warehouseType from TwmWarehouses where 1=1 ';
sOtherSQL := '';
if not IsEmpty(edtWarehouseStatus) then
sOtherSQL := ' and status=' + quotedStr(edtWarehouseStatus.Text);
if not IsEmpty(edtWarehouseNo) then
sOtherSQL := sOtherSQL + ' and warehouseNo=' + quotedStr(edtWarehouseNo.Text);
if not IsEmpty(edtWarehouseName) then
sOtherSQL := sOtherSQL + ' and warehouseName like ' + quotedStr('%' + edtWarehouseName.Text+'%');
if not IsEmpty(edtLocation) then
sOtherSQL := sOtherSQL + ' and Location like ' + quotedStr('%'+edtLocation.Text+'%');
if not IsEmpty(edtWarehouseType) then
sOtherSQL := sOtherSQL + ' and warehouseType= ' + quotedStr(edtWarehouseType.Text);
DMWM.cdsWMWarehouse.Close;
DMWM.cdsWMWarehouse.CommandText := sInitSQL + sOtherSQL;
DMWM.cdsWMWarehouse.Open;
end;

procedure TfrmwmWarehouse.spbStatusClick(Sender: TObject);
var
str: string;
begin
inherited;
str := 'select fieldValue, fieldMeaning from TddFieldMessage where tableName=' +
quotedStr('TwmWarehouses') + ' and fieldName=' + quotedStr('status');
untGet.GetData(edtWarehouseStatus, 'fieldValue', DMWM.dsLookups, str, 'fieldMeaning');
end;

procedure TfrmwmWarehouse.DBNavigator1BeforeAction(Sender: TObject;
Button: TNavigateBtn);
begin
// inherited;
if (Button = nbInsert) or (Button = nbEdit) then
dbeWarehouseName.SetFocus;
if Button = nbPost then
begin
{if DMWM.cdsWMWarehouse.State in [dsEdit] then
begin
DMWM.cdsLookups.Close;
DMWM.cdsLookups.CommandText := 'Update TwmWarehouses set warehouseName=' +
quotedStr(dbeWarehouseName.Text) + ', location=' + quotedStr(dbeLocation.Text) +
' where warehouseNo=' + quotedStr(dbeWarehouseNo.Text);
DMWM.cdsLookups.Execute;
DMWM.cdsWMWarehouse.ApplyUpdates(0);
Abort;
end;
}
end;

if Button = nbDelete then
begin
if not (DMWM.cdsWMWarehouse.FieldByName('status').AsString = 'N') then
begin
DMWM.cdsWMWarehouse.Edit;
DMWM.cdsWMWarehouse.FieldByName('status').AsString := 'D';
DMWM.cdsWMWarehouse.Post;
DMWM.cdsWMWarehouse.ApplyUpdates(0);
DMWM.cdsWMWarehouse.Refresh;
Abort;
end;
end;
end;

procedure TfrmwmWarehouse.ClearText(Sender: TObject);
begin
inherited;
edtWarehouseStatus.SetFocus;
end;

procedure TfrmwmWarehouse.spbWarehouseTypeClick(Sender: TObject);
begin
inherited;
untGet.GetData(edtWarehouseType, 'fieldValue', DMWM.dsLookups,
SSQL_WAREHOUSE_TYPE, 'fieldMeaning');
end;

procedure TfrmwmWarehouse.spbWarehouseTypeDBClick(Sender: TObject);
begin
inherited;
if dbeWarehouseType.DataSource.DataSet.State in [dsInsert, dsEdit] then
untGet.GetData(dbeWarehouseType, 'fieldValue', DMWM.dsLookups, SSQL_WAREHOUSE_TYPE, 'fieldMeaning');
end;

end.
 
后退
顶部