现在后台有一个线程往后台的TClientDataSet写数据,同时前台界面实时刷新但恶心的是,因为是数据感知控件,导致用户也可以在前台移动当前行,这使得后台在利用
if DataSet.Locate(...) then
begin
  DataSet.Edit;
  DataSet.FieldByName('aaa').AsString := '111';
  DataSet.FieldByName('bbb').AsString := '222';
  DataSet.FieldByName('ccc').AsString := '333';
  DataSet.Post;
end;
进行更新,更新到一半导致出错,应该如何解决?

解决方案 »

  1.   

    我曾考虑过如下方法:
    我在DBGrid的WindowProc里试图拦截用户界面的消息,通过信号量来实现与写DataSet的线程实现同步,但是无法知道界面所有可能导致当前位置发生改变的消息请教高手成功一定给分
      

  2.   

    dataset.DisableControls;
    ....................................
    dataset.EnableControls;
      

  3.   

    DisableControls/EnableControls我已经试验过,数据刷新非常频繁的情况下,仍然会导致更新错误。即在DisableControls情况下,后台记录仍然可以根据前台的用户输入发生位置变更
      

  4.   

    我大致的代码
      with ClientDataSet,InsertBuff do
      begin
        DisableControls;
        SavePlace := GetBook;    try
          if not Locate('PKey', VarArrayOf([PkField]), []) then
            Insert
          else Edit;      FieldByName('F1'.AsString:=Field1;
          FieldByName('F2').AsString:=Field2;
          FieldByName('F3').AsString:=Field3;
          ...
          Post;
        finally
          GotoBook(SavePlace);      FreeBook(SavePlace);      EnableControls;
        end;
      end;
      

  5.   

    我大致的解决思路在DBGRID的WINDOWPROC里面截获了所有的用户输入消息,对其中可能导致后台数据集发生移动的
    WM_VSCROLL等消息加了信号量,同时在写数据集的过程中,也加了信号量,保证在写的时候,锁定用户输入。但是这样效率太低,因为后台数据更新相当快。不知道DELPHI相关控件是否有类似的处理机制?
      

  6.   

    对于你这种应用,前面的显示不需要实时刷新(没有必要,客户也看不过来)假设你的后台TClientDataSet是cdsData1,你再用cdsData2关联用户界面的datasource然后定时(比如1秒)执行
    lock;
    try
      cdsdata2.data ;= cdsdata1.data;
    finally
      unlock;
    end;