Midas三层结构,客户端经常死锁,请高手帮忙

yhloveys 2008-07-10 05:50:43
结构:Client(SocketConnection) + Server(RemoteDataModule ) + DataBase(sql server 2000)

Server上维护一些测量程序名,以及对应的点位,和一些测量参数
Client上对测量仪器所测量的测量数据时实监控,用的是一个多线程.
每次获取到数据文件,都会通过ClientDataSet传递到Server端.然后在Server端进行点位比对,数据检验,添加合格标志.
再把这些信息通过OleVariant返回到Client.
Client的数量有16

现在遇到的问题就是Client在使用过程中,经常无缘无故的死掉,而且重新登陆连接还是无法连接到Server.
我有打开scktsrvr.exe查看用户数,上面会有同一个用户的多个连接在上面,所以导致该用户无法再连接,只有把scktsrvr.exe重新启动以后,又没有问题,可以用几个小时,过后又是这样.


下面是我Server上RemoteDataModule中的两个函数
function TQPDMRDM.CheckAllAvriable(List: OleVariant;
const prg_name: WideString): WideString;
var
// a : Tdata;
str_sql: String;
variable_name ,addflag: String;

temp_str : String;
begin
temp_str := '';

str_sql := 'SELECT * FROM v_variable WHERE FOLDER_NAME='''+ trim(prg_name)+'''';
adoquery1.Close;
adoquery1.SQL.Clear;
adoquery1.SQL.Add(str_sql);
adoquery1.Open;

ClientDataSet1.Data := List;


if adoquery1.RecordCount > 0 then
begin
adoquery1.First;
while not adoquery1.Eof do
begin
variable_name :=trim(adoquery1.fieldbyname('variable_name').AsString);
if not ClientDataSet1.Locate('variable_name',variable_name,[]) then
begin//用比这更优的比对方法吗??
if temp_str <> '' then
temp_str := temp_str + ',';
temp_str := temp_str + variable_name;
end;
adoquery1.Next;
end;
end;
ClientDataSet1.EmptyDataSet;
adoquery1.Close;
Result := temp_str;
end;



function TQPDMRDM.InsertAll(Ole_DataSet: OleVariant; const prg_name,
computername: WideString): OleVariant;
var
addflag :String;
D_value : Double;
s_Variable,S_datetime : String;
ok_flag : Integer;
begin
try
try
cds_temp.CreateDataSet;

ClientDataSet1.Data := Ole_DataSet;
try
// frm_main.mainconn.BeginTrans; //开始事务处理
ClientDataSet1.First;
while not ClientDataSet1.Eof do
begin
D_value := strTOFloat(ClientDataSet1.FieldValues['value']);
S_Variable := ClientDataSet1.FieldValues['variable_name'];
S_datetime := ClientDataSet1.FieldValues['date_time'];

try
addflag := TFunc.addFlag(D_value,prg_name,S_Variable);
except
addflag := '' ;
end;

ok_flag:=self.checkfields(prg_name,S_variable,floatTOstr(D_value));
case ok_flag of
0:
begin
end;
1: //合格数据
begin
saveInspData(S_datetime,floatTOstr(D_value),trim(computerName),trim(addflag));

cds_temp.Append;
cds_temp.FieldByName('variable_name').AsString := S_Variable;
cds_temp.FieldByName('value').AsString := floatTOstr(D_value);
cds_temp.FieldByName('date_time').AsString := S_datetime;
cds_temp.FieldByName('flag').AsBoolean :=true ;
cds_temp.FieldByName('addflag').AsString := addflag;
cds_temp.FieldByName('usl_value').AsString := floatTOstr(usl_value1);
cds_temp.FieldByName('target_value').AsString := floatTOstr(target_value1);
cds_temp.FieldByName('lsl_value').AsString := floatTOstr(lsl_value1);
cds_temp.Post;
end;
2: //不合格数据
begin
saveNoInspData(S_datetime,floatTOstr(D_value),trim(computerName),trim(addflag));

cds_temp.Append;
cds_temp.FieldByName('variable_name').AsString := S_Variable;
cds_temp.FieldByName('value').AsString := floatTOstr(D_value);
cds_temp.FieldByName('date_time').AsString := S_datetime;
cds_temp.FieldByName('flag').AsBoolean :=false ;
cds_temp.FieldByName('addflag').AsString := addflag;
cds_temp.FieldByName('usl_value').AsString := floatTOstr(usl_value1);
cds_temp.FieldByName('target_value').AsString :=floatTOstr(target_value1);
cds_temp.FieldByName('lsl_value').AsString := floatTOstr(lsl_value1);
cds_temp.Post;
end;
end;
ClientDataSet1.Next;
end;
// frm_main.mainconn.CommitTrans; //提交事务
ClientDataSet1.EmptyDataSet;
result := cds_temp.Data;
except
on e:Exception do
begin
// frm_main.mainconn.RollbackTrans;//当有错误时,回滚事务
ClientDataSet1.EmptyDataSet;
cds_temp.EmptyDataSet;
frm_main.memo_System.Lines.Add(formatdatetime('yyyy-mm-dd hh:nn:ss ',now)+e.Message);
end;
end;
finally
cds_temp.EmptyDataSet;
end;
except
on e:Exception do
begin
frm_main.memo_System.Lines.Add(formatdatetime('yyyy-mm-dd hh:nn:ss ',now)+e.Message);
cds_temp.EmptyDataSet;
end;
end;


下面是Client上多线程中调用Server的一个函数部份代码:
m_ah.ShowMsg('开始到服务器上检测variable 的完整性',1);
try
miss_String:=ClientDM.scktconn.AppServer.CheckAllAvriable(ClientDM.ClientDataSet3.Data,str_pro); //调用服务器上的函数
except
on e:Exception do
m_ah.ShowMsg('到服务器上检查variable出错:'+e.Message);
end;
m_ah.ShowMsg('完整性检查结束',1);
if miss_String <> '' then
begin
tag1 := 'Miss Data';
m_ah.ShowMsg('variabel不完整,缺少:'+miss_string+'开始打开缺少variable界面',1);
pro_name := trim(str_pro);
miss_tag := true;
// SendMessage(frm_main.Handle,WM_USER + 2, 5, 0); //打开missForm窗口,线程不停止
end
else
begin
tag1 := 'NO Miss';
pro_name := trim(str_pro);
TRY
m_ah.ShowMsg('开始到服务器上插入数据,',1);
frm_main.cdsBase.Data := ClientDM.scktconn.AppServer.InsertAll(ClientDM.ClientDataSet3.Data,str_pro,computerName);//调用Server上的函数
m_ah.ShowMsg('插入数据到服务器成功',1);
frm_main.Edit1.Text := trim(str_pro);
EXCEPT
on e:exception do
begin
m_ah.ShowMsg('插入数据到服务器上出错:'+e.Message);
frm_main.Edit1.Text := '';
frm_main.cdsBase.EmptyDataSet;
end;
end;
end;
end;
end;


请高手帮忙看看,到底哪里有问题了
...全文
333 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
很土 2008-12-16
  • 打赏
  • 举报
回复
可以试试使用GCI, 下载地址: http://download.csdn.net/source/255772
vagerent 2008-12-16
  • 打赏
  • 举报
回复
应该考虑升级到CBX RIA框架下,Delphi7的。中间层无状态,完全避免了死锁。
讨论QQ群:16169282
nbzip 2008-09-19
  • 打赏
  • 举报
回复
服务器压力太大,也会死客机的.(连接时,走神,客机连不上,死连).

你可以在测试中,用一二台机器,做个测试.看看一二台机器连测试服务器,死机的概率高不高.

如果一二台都顶不住,是你程序有问题(服务端),噢,网络之间也要测试一样,发一个大的文件,如一G的,在三四台机器上传来传去.
会不会出现错误(接来文件是不是可以打开).

客户端这边,尽最不要死连,连一,二次就报个错...退出就行了.
zhuchengchuan 2008-09-19
  • 打赏
  • 举报
回复
6楼的说得对,有这种可能;还有,你在服务器程序中有没有Showmessage,如果有,必须去掉,否则,一旦showmessage,所有的客户端都会死机;
壹志凝神 2008-09-07
  • 打赏
  • 举报
回复
把sockconnection 的好像叫callback参数设为false 试试
Bear_hx 2008-09-04
  • 打赏
  • 举报
回复
对加入运行日志,首先要定位死锁在那儿,然后才能想办法解决。
kugoo_2006 2008-09-04
  • 打赏
  • 举报
回复
同意楼上的
fangsp 2008-09-04
  • 打赏
  • 举报
回复
加入运行日子吧 这样分析起来快些
iamduo 2008-09-03
  • 打赏
  • 举报
回复
不会。学习。
踢踏 2008-07-10
  • 打赏
  • 举报
回复
建议加入运行日志,看看在哪儿会出错。

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧