可以用线程来创建全局变量吗?(100分)(100分)

  • 主题发起人 主题发起人 earlyspring
  • 开始时间 开始时间
E

earlyspring

Unregistered / Unconfirmed
GUEST, unregistred user!
我用SOCKETSERVER来接收数据,一个用户时正常但在多个用户时就不行了,
程序提示ADO的状态不对我想通过线程来创建ADO控件,请问应该怎么做?
 
关注.向高手学习
 
建一个ADO数组,每个线程只能使用其中一个。
如果你的线程数量动态变化,那末线程开始处动态生成ADO对象,结束时销毁。
 
每一个线程动态创建ADO连接
 
回ArchangelQin:
主要在线程中创建的ADO对象,需要在其它过程中用,所以就必须创建一个全局的,
但是在socketserver的READ事件中用时,有可能会有多个用户同时连接,这样造成了ADO
对象状态的冲突,请教这个问题该怎样解决?有源码吗?谢谢了!
 
如果仅仅是访问数据库,一个ADO应该够了,而且socket还向没必要吧(直接用SQL)。
要是你想把请求在服务器端转为SQL,你应该建立一个缓冲区,应对同时来多个查询请求。
我只用C实现过这种情况,网络接收请求,放入缓冲队列(自建),另一个线程一个接一个的慢慢处理。这样就不会同时处理多个了。
可能复杂了一些,不知道你到底要干什么?
 
回ArchangelQin:
首先多谢你的耐心指教,下面的是我的serverSocket1ClientRead中的源码,
问题:当然一个用户连接时没有问题,当两个或多个用户连接传输入数据时,
会提示ADO对象已经打开,也就是说两个用户共用一个ADO对象,这时候出现了冲突,
如一个用户正在关闭,另一个用户需要打开,这时就出错了,请问怎么解决?
多谢谢了!!!
源码如下:
procedure TForm1.serverSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
i:integer;
sendstr:string;
newmobilenum,newcommid:string;
newplace:integer;
newstr:array[1..11] of string;
newreport:array[1..8] of string;
hzstr:array[1..5] of string;
clientstr:array[1..6] of string;
myadodata:tadodata;
begin
msg:='';
sendstr:='';
mycon:=socket.Data;
if mycon.currstatus=0 then
begin
msg:=Socket.ReceiveText;
memo1.Lines.Add(msg);
shopid:=msg;
if adoserver.Active then
adoserver.Close;
adoconnection1.ConnectionString:=conn;
adoserver.Connection:=adoconnection1;
adoserver.CommandText:='select * from SMS_Shop where shopid='''+shopid+'''';
try
adoserver.Active:=true;
except
memo1.Lines.Add('无法建立数据库联接');
end;
memo1.Lines.Add(inttostr(adoserver.RecordCount));
if adoserver.recordcount=0 then
begin
socket.SendText('250shopiderror');
socket.Close;
exit;
end
else
begin
socket.SendText('250shopidpass');

mycon.currstatus:=1;
socket.data:=mycon;
exit;
end;
adoserver.Close;
end;
//---------------- mycon.currstatus=1-----------------------------------
if mycon.currstatus=1 then
begin
if adocheck.Active then
adocheck.Close;
adocheck.Connection:=adoconnection1;
adocheck.CommandText:='select * from SMS_ShopUpdate_Temp where shopid='''+shopid+'''';
adocheck.Active:=true;
msg:=socket.ReceiveText;
memo1.Lines.Add(msg);
if msg='readyok' then
begin
if adocheck.recordcount=0 then
begin
socket.sendtext('250updateno');
memo1.Lines.add('250updateno');
mycon.currstatus:=4;
socket.data:=mycon;
exit;
end
else
begin
socket.sendtext('250updateyes');
memo1.Lines.add('250updateyes');
mycon.currstatus:=2;
socket.data:=mycon;
exit;
end;
end;
end;
//-----------------------mycon.currstatus=2-----------------------
if mycon.currstatus=2 then
begin
if adocheck.recordcount=0 then
begin
socket.SendText('updateno');
memo1.Lines.Add('send:updateno');
mycon.currstatus:=4;
socket.data:=mycon;
exit;
end;
msg:=socket.ReceiveText;
memo1.Lines.Add('Rec:'+msg);
if msg='itemready' then
begin
if adoserver.Active then
adoserver.Close;
adoserver.Connection:=adoconnection1;
adoserver.CommandText:='select * from Sms_UpdateItem_Temp';
adoserver.Active:=true;
if adoserver.recordcount>0 then
begin
adoserver.First;
for i :=1 to adoserver.RecordCountdo
begin
sendstr:='##'+sendstr+adoserver.fieldbyname('commid').AsString+'##'+adoserver.fieldbyname('remark').AsString;
adoserver.Next;
end;
socket.SendText(sendstr);
adoserver.First;
if adocheck.recordcount=1 then
begin
for i:=1 to adoserver.RecordCountdo
begin
adoserver.Delete;
adoserver.Next;
end;
end;
adoserver.Close;

memo1.Lines.Add('send:'+sendstr);
mycon.currstatus:=3;
socket.Data:=mycon;
exit;

end
else
begin
socket.SendText('itempass');
memo1.Lines.Add('send:itempass');
mycon.currstatus:=3;
socket.data:=mycon;
exit;
end;
end;
end;
//---------------------mycon.currstatus:=3;-------------------------
if mycon.currstatus=3 then
begin
if adocheck.recordcount=0 then
begin
socket.SendText('mobielpass');
memo1.Lines.Add('send: mobilepass');
mycon.currstatus:=4;
socket.data:=mycon;
exit;
end;
msg:=socket.ReceiveText;
if msg='mobileok' then
begin
if adoserver.Active then
adoserver.Close;
adoserver.Connection:=adoconnection1;
adoserver.CommandText:='select * from Sms_MobileUpdate_Temp';
adoserver.Active:=true;
if adoserver.recordcount=0 then
begin
socket.SendText('mobielpass');
memo1.Lines.Add('send: mobilepass');
mycon.currstatus:=4;
socket.data:=mycon;
exit;
end
else
begin
for i:=1 to adoserver.RecordCountdo
begin
sendstr:='';
sendstr:='mobile:'+adoserver.fieldbyname('type').AsString+'type:'+adoserver.fieldbyname('name').AsString;
socket.SendText(sendstr);
adoserver.Next;
end;
if adocheck.recordcount=1 then
begin
adoserver.First;
for i:=1 to adoserver.RecordCountdo
begin
adoserver.Delete;
adoserver.Next;
end;
end;
adoserver.Close;
socket.SendText('mobielpass');
memo1.Lines.Add('send: mobilepass');
mycon.currstatus:=4;
socket.data:=mycon;
exit;
end;
end;
end;
//---------------mycon.currstatus=4------------------------
if mycon.currstatus=4 then
begin
msg:=socket.ReceiveText;
if msg='orderredy' then
begin
socket.SendText('serverok');
memo1.Lines.Add('send:serverok');
mycon.currstatus:=5;
socket.Data:=mycon;
exit;
end;
end;
//--------------mycon.currstatus=5 接收订阅------------------------
if mycon.currstatus=5 then
begin
msg:=socket.ReceiveText;
if msg='reportready' then
begin
socket.SendText('serverreportready');
memo1.Lines.add('--dealer orders received over!');
memo1.Lines.Add('begin
to receive the report!');
mycon.currstatus:=6;
socket.Data:=mycon;
exit;
end
else
begin
msg:=copy(msg,11,length(msg)-10);
newplace:=pos('commid:',msg);
newmobilenum:=copy(msg,1,newplace-1);
msg:=copy(msg,newplace+7,length(msg)-newplace-6);
newcommid:=msg;
if adoserver.Active then
adoserver.Close;
adoserver.Connection:=adoconnection1;
adoserver.CommandText:='select * from T_Dealer_Order_Temp where mobilenum='''+newmobilenum+''' and order_commid='''+newcommid+'''';
adoserver.Active:=true;
if adoserver.recordcount=0 then
begin
adoserver.Append;
adoserver.FieldByName('mobilenum').AsString:=newmobilenum;
adoserver.FieldByName('order_commid').AsString:=newcommid;
adoserver.Post;
end;

adoserver.Close;
exit;
end;
end;
//------------------mycon.currstatus=6---------------------------------------
if mycon.currstatus=6 then
begin
msg:='';
msg:=socket.ReceiveText;
if msg='billready' then
begin
socket.SendText('serverbillready');
memo1.Lines.Add('准备接收流水帐!');
mycon.currstatus:=7;
socket.Data:=mycon;
exit;
end
else
begin
msg:=copy(msg,4,length(msg)-3);
for i:=1 to 11do
begin
newplace:=pos('###',msg);
newstr:=copy(msg,1,newplace-1);
msg:=copy(msg,newplace+2,length(msg)-newplace-2);
end;
if adoserver.Active then
adoserver.Close;
adoserver.Connection:=adoconnection1;
adoserver.CommandText:='select * from T_Daily_Report where report_no='''+newstr[1]+'''';
adoserver.Active:=true;
if adoserver.recordcount=0 then
adoserver.Append
else
adoserver.Edit;
adoserver.FieldByName('Report_No').AsString:=newstr[1];
adoserver.FieldByName('Sales_Condition').AsString:=newstr[2];
adoserver.FieldByName('Clock_Condition').AsString:=newstr[3];
adoserver.FieldByName('Morning_Meeting').asstring:=newstr[4];
adoserver.FieldByName('Client_Response').AsString:=newstr[5];
adoserver.FieldByName('After_Service').AsString:=newstr[6];
adoserver.FieldByName('Sales_Promotion').AsString:=newstr[7];
adoserver.FieldByName('Field_Related').AsString:=newstr[8];
adoserver.FieldByName('Emergency_Handling').AsString:=newstr[9];
adoserver.FieldByName('people').AsString:=newstr[10];
adoserver.FieldByName('Remark').AsString:=newstr[11];
adoserver.Post;
adoserver.Close;
exit;
end;
end;
//--------------------mycon.currstatus=7-----------------------------
if mycon.currstatus=7 then
begin
msg:='';
msg:=socket.ReceiveText;
if msg='clienthelp' then
begin
socket.SendText('serverhelpready');
memo1.Lines.Add('准备接收汇总报表....');
mycon.currstatus:=8;
socket.Data:=mycon;
exit;
end
else
begin
msg:=copy(msg,4,length(msg)-3);
for i:=1 to 8do
begin
newreport:='';
newplace:=pos('###',msg);
newreport:=copy(msg,1,newplace-1);
msg:=copy(msg,newplace+3,length(msg)-newplace-2);
end;
if adoserver.Active then
adoserver.close;
adoserver.CommandText:='select * from T_Daily_Bill where Dealer_Id='''+shopid+'''';
adoserver.Active:=true;
if adoserver.recordcount=0 then
adoserver.Append
else
adoserver.Edit;
adoserver.FieldByName('Dealer_Id').AsString:=newreport[1];
adoserver.FieldByName('Supplier_Id').AsString:=newreport[2];
adoserver.FieldByName('Type_Id').AsString:=newreport[3];
adoserver.FieldByName('IMEI').AsString:=newreport[4];
adoserver.FieldByName('bill_time').AsDateTime:=strtodate(newreport[5]);
adoserver.FieldByName('Operation').AsString:=newreport[6];
adoserver.FieldByName('Price').AsString:=newreport[7];
adoserver.FieldByName('Employee').AsString:=newreport[8];
adoserver.Post;
adoserver.Close;
exit;
end;
end;
//---------------------- mycon.currstatus=8-----------------------------
if mycon.currstatus=8 then
begin
msg:='';
msg:=socket.ReceiveText;
memo1.Lines.Add(msg);
if msg='clientclients' then
begin
socket.SendText('serverclientsready');
memo1.Lines.Add('准备接收客户资料!');
mycon.currstatus:=9;
socket.Data:=mycon;
exit;
end
else
begin
msg:=copy(msg,4,length(msg)-3);
for i:=1 to 5do
begin
hzstr:='';
newplace:=pos('###',msg);
hzstr:=copy(msg,1,newplace-1);
msg:=copy(msg,newplace+3,length(msg)-newplace-2);
end;
if adoserver.Active then
adoserver.Close;
adoserver.Connection:=adoconnection1;
adoserver.commandtext:='select * from T_Daily_Bill_Help where store_id='''+hzstr[1]
+''' and dealer_id='''+hzstr[2]+''' and typeid='''+hzstr[3]
+''' and operation='''+hzstr[5]+'''';
adoserver.Active:=true;
if adoserver.RecordCount=0 then
adoserver.Append
else
adoserver.Edit;
adoserver.FieldByName('store_id').AsString:=hzstr[1];
adoserver.FieldByName('dealer_id').AsString:=hzstr[2];
adoserver.FieldByName('type_id').AsString:=hzstr[3];
adoserver.FieldByName('mobilecount').AsInteger:=strtoint(hzstr[4]);
adoserver.FieldByName('opertiem').AsString:=hzstr[5];
adoserver.Post;
adoserver.Close;
exit;

end;
end;
//-------------------------mycon.currstatus=9---------------
if mycon.currstatus=9 then
begin
msg:='';
msg:=socket.ReceiveText;
memo1.Lines.Add(msg);
if msg='transeover' then
begin
memo1.Lines.Add(socket.RemoteAddress+shopid+'数据交换完毕!') ;
exit;
end
else
begin
msg:=copy(msg,4,length(msg)-3);
for i:=1 to 6do
begin
clientstr:='';
newplace:=pos('###',msg);
clientstr:=copy(msg,1,newplace-1);
msg:=copy(msg,newplace+3,length(msg)-newplace-2);
end;
if adoserver.Active then
adoserver.Close;
adoserver.Connection:=adoconnection1;
adoserver.CommandText:='select * from T_Clients where imei='''+clientstr[1]+'''';
adoserver.Active:=true;
if adoserver.RecordCount=0 then
adoserver.Append
else
adoserver.Edit;
adoserver.FieldByName('IMEI').AsString:=clientstr[1];
adoserver.FieldByName('Name').AsString:=clientstr[2];
adoserver.fieldbyname('Id_Card').AsString:=clientstr[3];
adoserver.FieldByName('Phone_No').AsString:=clientstr[4];
adoserver.FieldByName('Mobile_No').AsString:=clientstr[5];
adoserver.FieldByName('Type_Id').AsString:=clientstr[6];
adoserver.Post;
exit;
end;
end;
end;
 
AdO单线程法
使用ADO的connection 在过程中创建ADOQuery
多线程法
memo不具备线程安全,注意安全处理(就是到主线程中处理此部分,其实还是在主线程中排队处理)
 
procedure TForm1.serverSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
中的内容改为
procedure TForm1.serverSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
th:TYourConstrolThread;
begin
th := TYourConstrolThread.Create(把Socket作为参数传过去);
th.resume;
end;
所有在TYourConstrolThread;中处理
处理完后自己销毁线程
 
后退
顶部