在客户端点击了ApplyUpdate(0)三次后,应用服务器程序就死机了,我是照李维老师的那本系统篇的例子做的。
服务器端:有一个窗口,上面有一个DBGRID,是显示客户端传过来的要更新的数据,当客户端点击applyUpdate(0)三次后,这个表DBGRID就不会显示了,发生死机。
DBGRID的ClientDataset1的数据是直接在Provider的onUpdateData事件赋值的。
procedure TMySevenMultiSrv.sgUpdateSQLProviderUpdateData(Sender: TObject;
  DataSet: TCustomClientDataSet);
var
  iCount1,iCount2:integer;
begin
  Form1.ClientDataSet1.Data:=DataSet.Data;
  ...
end;
按F8单步执行时,代码都是正常执行,但就是在窗口显示中,DBGRID会发生死机。真是弄不明白。程序源代码如下:
---Server.pas
unit Server;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, DBClient, Grids, DBCtrls, DBGrids, ExtCtrls, ComCtrls;type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    DBGrid1: TDBGrid;
    DBNavigator1: TDBNavigator;
    StringGrid1: TStringGrid;
    ClientDataSet1: TClientDataSet;
    DataSource1: TDataSource;
    StatusBar1: TStatusBar;
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}end.--ServerDM.pas
unit ServerDM;{$WARN SYMBOL_PLATFORM OFF}interfaceuses
  Windows, Messages, SysUtils, Classes, ComServ, ComObj, VCLCom, DataBkr,
  DBClient, ServerApp_TLB, StdVcl, Provider, DB, ADODB;type
  TMySevenMultiSrv = class(TRemoteDataModule, IMySevenMultiSrv)
    ADOConnection1: TADOConnection;
    ADOQuery1: TADOQuery;
    sgUpdateSQLProvider: TDataSetProvider;
    sgUpdateDataSetProvider: TDataSetProvider;
    ADOQuery2: TADOQuery;
    procedure ADOQuery2BeforePost(DataSet: TDataSet);
    procedure ADOQuery2AfterPost(DataSet: TDataSet);
    procedure sgUpdateSQLProviderUpdateData(Sender: TObject;
      DataSet: TCustomClientDataSet);
  private
    { Private declarations }
  protected
    class procedure UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); override;
  public
    { Public declarations }
  end;implementationuses Server;{$R *.DFM}procedure TMySevenMultiSrv.ADOQuery2AfterPost(DataSet: TDataSet);
begin
  Form1.StatusBar1.Panels[0].Text:='After Post被触发了!';
end;procedure TMySevenMultiSrv.ADOQuery2BeforePost(DataSet: TDataSet);
begin
  Form1.StatusBar1.Panels[1].Text:='Before Post被触发了!';
end;procedure TMySevenMultiSrv.sgUpdateSQLProviderUpdateData(Sender: TObject;
  DataSet: TCustomClientDataSet);
var
  iCount1,iCount2:integer;
begin
  Form1.ClientDataSet1.Active:=false;
  Form1.ClientDataSet1.Data:=DataSet.Data;
  Form1.ClientDataSet1.Active:=True;
  Form1.StringGrid1.ColCount:=0;
  Form1.StringGrid1.RowCount:=0;
  Form1.StringGrid1.ColCount:=Dataset.FieldCount;
  Form1.StringGrid1.RowCount:=Dataset.RecordCount;
  for icount1 := 0 to Dataset.FieldCount - 1 do
     Form1.StringGrid1.Cells[iCount1,0]:=Dataset.Fields[iCount1].FieldName;  for iCount1 := 0 to Dataset.RecordCount-1 do
  begin
    for iCount2 := 0 to DataSet.FieldCount - 1 do
    begin
       if (pfInUpdate in DataSet.Fields[iCount2].ProviderFlags) then
          Form1.StringGrid1.Cells[iCount2,iCount1+1]:=Form1.StringGrid1.Cells[iCount2,iCount1+1]+
                      ' pfInUpdate';
       if (pfInWhere in DataSet.Fields[iCount2].ProviderFlags) then
          Form1.StringGrid1.Cells[iCount2,iCount1+1]:=Form1.StringGrid1.Cells[iCount2,iCount1+1]+
                      ' pfInWhere';
       if (pfInKey in Dataset.Fields[icount2].ProviderFlags) then
          Form1.StringGrid1.Cells[iCount2,iCount1+1]:=Form1.StringGrid1.Cells[iCount2,iCount1+1]+
                      ' pfInKey';
       if (pfHidden in Dataset.Fields[iCount2].ProviderFlags) then
          Form1.StringGrid1.Cells[iCount2,iCount1+1]:=Form1.StringGrid1.Cells[iCount2,iCount1+1]+
                      ' pfHidden';
    end;
  end;
end;class procedure TMySevenMultiSrv.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string);
begin
  if Register then
  begin
    inherited UpdateRegistry(Register, ClassID, ProgID);
    EnableSocketTransport(ClassID);
    EnableWebTransport(ClassID);
    RegisterPooled(ClassID,10,10,True);
  end else
  begin
    DisableSocketTransport(ClassID);
    DisableWebTransport(ClassID);
    UnRegisterPooled(ClassID);
    inherited UpdateRegistry(Register, ClassID, ProgID);
  end;
end;initialization
  TComponentFactory.Create(ComServer, TMySevenMultiSrv,
    Class_MySevenMultiSrv, ciMultiInstance, tmApartment);
end.--客户端代码:
unit Client;interfaceuses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, DBCGrids, ExtCtrls, DBCtrls, Db, DBClient, MConnect, Mask;type
  TForm2 = class(TForm)
    DCOMConnection1: TDCOMConnection;
    ClientDataSet1: TClientDataSet;
    DBNavigator1: TDBNavigator;
    Button1: TButton;
    Edit1: TEdit;
    DBCtrlGrid1: TDBCtrlGrid;
    Label1: TLabel;
    DBEdit1: TDBEdit;
    DataSource1: TDataSource;
    Label2: TLabel;
    DBEdit2: TDBEdit;
    Label3: TLabel;
    DBEdit3: TDBEdit;
    Label4: TLabel;
    DBEdit4: TDBEdit;
    Label5: TLabel;
    DBEdit5: TDBEdit;
    Label6: TLabel;
    DBEdit6: TDBEdit;
    Label7: TLabel;
    DBEdit7: TDBEdit;
    Label8: TLabel;
    DBEdit8: TDBEdit;
    Label9: TLabel;
    DBEdit9: TDBEdit;
    Label10: TLabel;
    DBEdit10: TDBEdit;
    Label11: TLabel;
    DBEdit11: TDBEdit;
    Button2: TButton;
    ClientDataSet2: TClientDataSet;
    Edit2: TEdit;
    Button3: TButton;
    ClientDataSet1customerID: TWideStringField;
    ClientDataSet1CompanyName: TWideStringField;
    ClientDataSet1contactName: TWideStringField;
    ClientDataSet1ContactTitle: TWideStringField;
    ClientDataSet1Address: TWideStringField;
    ClientDataSet1City: TWideStringField;
    ClientDataSet1Region: TWideStringField;
    ClientDataSet1Postalcode: TWideStringField;
    ClientDataSet1Country: TWideStringField;
    ClientDataSet1phone: TWideStringField;
    ClientDataSet1fax: TWideStringField;
    procedure ClientDataSet1AfterPost(DataSet: TDataSet);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure ClientDataSet2AfterPost(DataSet: TDataSet);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form2: TForm2;implementation{$R *.DFM}procedure TForm2.ClientDataSet1AfterPost(DataSet: TDataSet);
begin
  Edit1.Text := IntToStr(ClientDataSet1.ChangeCount);
end;procedure TForm2.Button1Click(Sender: TObject);
begin
  ClientDataSet1.ApplyUpdates(0);
  ClientDataSet1.Refresh;
end;procedure TForm2.Button2Click(Sender: TObject);
begin
  ClientDataSet2.ApplyUpdates(0);
//  ClientDataSet2.Refresh;
end;procedure TForm2.ClientDataSet2AfterPost(DataSet: TDataSet);
begin
  Edit2.Text := IntToStr(ClientDataSet2.ChangeCount);
end;procedure TForm2.Button3Click(Sender: TObject);
begin
  if DataSource1.DataSet = ClientDataSet1 then
    DataSource1.DataSet := ClientDataSet2
  else
    DataSource1.DataSet := ClientDataSet1;
end;end.