procedure TMainFrm.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
  var
  Fcsstr,Splitstr,MobileID,MesStr,RecTime:string; //公共变量
  FCSID,FCSTime:string;//协议3.0部份内容变量,FCS登陆
  jobNo,ReauestDate,RequestTime,JobDetail,Re,Jobstatus,RoomNo,Escal,Ack:string;//协议3.2部份内容变量 ,工作请求状态
  UpdateStatus:string;//协议3.3部份内容变量 ;工作状态更新
  Messagestr,MsgType,MsgNo,MsgACK:string; //协议3.8部份内容变量 ;特急信息发送  ProcotolID,Isend,i:integer;
  Fitem,Sitem:Tlistitem;
begin
......//省略是一些数据解析代码
//此处将GB2312中文的解码格式转换为unicode通用中文解码格式
    Messtr:=UTF8Encode(Messtr);
    Messtr:=UTF8Decode(Messtr);    if (MobileID<>'') and (strtoint(copy(mobileID,1,1)) in [0..9]) and (length(Messtr)>1) and (pos(chr(16),Messtr)=0) then //此处判断显示的条件
    begin
        with datamodule1.ADOSendFcsM do//这里是adoconnetion2连接
        begin
            close;
            sql.Clear;
            sql.Add('select * from sendFcsM');
            open;
            append;
            fieldbyname('SendFcsMobile').Asstring:=MobileID;
            fieldbyname('SendFcStr').Asstring:=Messtr;
            fieldbyname('Sendstatus').AsString:='0';
            fieldbyname('date').AsString:=formatdatetime('yyyy-mm-dd hh:nn:ss',now);
            post;
        end;
    end;
    sleep(100);
  if checkbox3.Checked=true then
  begin
     memo3.Lines.Add('RECFcs:'+datetimetostr(now())+'  '+MobileID+'#'+Messtr);
  end;
end;procedure SendThread.SendPro;
var
SendMobile,SendSMS:string;
Fitem:Tlistitem;
begin
with datamodule1.ADOSFMess do//这是adoconnetion1连接的
begin
    close;
    sql.Clear;
    sql.Add('select * from sendFcsM');
    open;
    if recordcount>0 then
    begin
        while not eof do
        begin
            mainfrm.sendmessage:='';
            mainfrm.SendPhoneStr:='';
            mainfrm.sendmessage:=trim(fieldbyname('SendFcStr').AsString);
            mainfrm.SendPhoneStr:=trim(fieldbyname('SendFcsMobile').AsString);
            mainfrm.Sendsms;      //发送短信  线程中不可以调用函数 ,但这个是过程
            //显示在列表中
            SendMobile:='';
            SendSMS:='';
            SendMobile:=trim(fieldbyname('SendFcsMobile').AsString);
            SendSMS:=trim(fieldbyname('SendFcStr').AsString);            Fitem:=mainfrm.listview2.Items.Add;
            if  InforConFrm.StatusBar1.Panels.Items[1].Text='信息发送成功' then
            begin
                Fitem.ImageIndex:=2;
                with datamodule1.ADOMSend do //保存的到已发送列表中,这是adoconnetion2连接的
                begin
                    close;
                    sql.Clear;
                    sql.Add('select * from Messsend');
                    open;
                    append;
                    fieldbyname('Mobile').AsString:=SendMobile;
                    fieldbyname('SendMessage').AsString:=SendSMS;
                    fieldbyname('SendDate').AsString:=formatdatetime('yyyy-mm-dd hh:nn:ss',now);
                    fieldbyname('SendUser').AsString:='FCSSend';
                    post;
                end;
                delete;  //保存后删除
                ExecSQL
            end else
            begin
                Fitem.ImageIndex:=0;   //Fitem.ImageIndex:=2;是发送成功
                next;
            end;
            Fitem.SubItems.Add(SendMobile);
            Fitem.SubItems.Add(SendSMS);
            Fitem.SubItems.Add(datetimetostr(now()));
            Application.ProcessMessages;
        end;
    end;
end;
end;
相关的数据库有关的操作就是上面这些,三五天就出现一次上面的错误提示“Access violation at address 4DD4186B in module 'msado15.dll'”不是时时都有,线程中也使用了临界同步,也使用了多个连接,所以现在不知问题出在那里了。
下面是调用线程同步的方法:
procedure SendThread.Execute;
begin
while not terminated   do
begin
    EnterCriticalSection(CS); //进入临界区
    synchronize(SendPro);
    Application.ProcessMessages;
end;
LeaveCriticalSection(CS); //离开临界区
end;

解决方案 »

  1.   

    http://topic.csdn.net/u/20070605/11/d9d2c7e0-50fe-476b-abbe-12d653d1a7db.html
      

  2.   

    谢谢shijies,但是你提供的链接中并没有完整的答案,或有效的解决方案,现在是在XP下运行,应当都是MADC2.7以下版本应当不是版本问题
      

  3.   

    大家能帮我看一下,在一个adoquery里面一个OPEN,然后因为要删除再用一个ExecSQL,是这个引起的冲突吗,但要是分成二个又是怎样的处理呢
      

  4.   

    跟踪都是没问题的,因为不是常出现,是偶发性的,而且三五天甚至一周以上才出现一次,而调用数据库操作的地方也就这几个地方,此一,所以集中怀疑是在线程中open之后delete删除之后,再ExecSQL,如果这里我去掉ExecSQL,是否可行(我有测试去掉ExecSQL,程序可以正常运行,并不会报错),但长久的话是不是会有影响。
      

  5.   

    Query.ExecSQL是用于执行insert,update,delete操作,无需返回数据集。
      

  6.   

    那对于一个数据的删除
    with adoquery1 do
    close;
    sql.clear;
    sql.add('select * from talbel1');
    open; 
    delete;
    end; 
    与下面的程序的作用是没有区别的了
    with adoquery1 do
    close;
    sql.clear;
    sql.add('delete * from talbel1');
    ExecSQL; 
    end;