DX10下面WSASocket阻塞的情况

今天帮群友调程序,说是程序会卡在WSASocket这一句。看CallStack

 

大概的流程是这样的

Application.Run –> LoadLibrary(A.dll, 带包bpl)->diocp.socket.utils( 初始化单元) –> loadIocpExFunction->WSASocket(阻塞了)

 

后来在主程序中引用diocp.socket.utils单元,使得初始化WSASocket提前到EXE中完成,一切正常

【杂谈接口】-Delphi中使用接口的一些注意事项

原则一:

   如果一个接口需要as成其他接口使用, 如果该接口的实例在该过程中可能会被释放,那么最好将 as 的接口用临时变量保存起来, 然后在使用完后及时将临时接口:= nil;

   如果用as成其他接口直接使用时(如  (lvIntf as IOpera).DoSomething() )系统会自动生成临时变量,存放对应的接口,然后在过程退出时,进行接口变量清理时,会触发接口实例的_release方法。如果对应实例的内存块被破坏,就有可能会导致访问违规的异常。

// 下面这段执行时可能会出现AV异常
var
  lvPlugin: IPlugin;
  lvStoProcessor   : IStoProcessor;
begin
  //物料库存_逻辑处理
  lvPlugin := FPluginConsole.CreatePlugin('STOLogic');
  try
    lvPlugin.PrepareForCreate;
    
    with lvPlugin as IStoProcessor do
    begin
      //处理结存
      DoOnHand(pvFormKey, OPERA_UNAPPR);
      CheckNegative(pvFormKey);
    end;
  finally
    lvPlugin.FreePlugin;
    lvPlugin := nil;
  end;

  // 执行库存处理后的其他脚本
  ExecuteAfterScript(pvFormKey, FJsnConfig.O['STO']);

end;



// 这样做是最安全的
var
  lvPlugin: IPlugin;
  lvStoProcessor   : IStoProcessor;
begin
  //物料库存_逻辑处理
  lvPlugin := FPluginConsole.CreatePlugin('STOLogic');
  try
    lvPlugin.PrepareForCreate;
    
    lvStoProcessor := lvPlugin as IStoProcessor;
    //处理结存
    lvStoProcessor.DoOnHand(pvFormKey, OPERA_UNAPPR);
    lvStoProcessor.CheckNegative(pvFormKey);

    lvStoProcessor := nil;
  finally
    lvPlugin.FreePlugin;
    lvPlugin := nil;
  end;

  // 执行库存处理后的其他脚本
  ExecuteAfterScript(pvFormKey, FJsnConfig.O['STO']);
end;

 

 

…. 未完待续

 

 

 

 

 

==========================================

DIOCP官方社区|MyBean官方社区

http://diocp.wedelphi.com/

==========================================

【DIOCP应用案例】-案例2(无毒公主)

案例2<无毒公主>

服务端应用场景:

金融行业交易行情、交易控制指令发布推送服务器。主要是要稳定和快速,对负载要求不高。日常在线20个左右。服务器和客户端都用的diocp实现的iocp异步模式。由于是金融类的应用,对稳定性和推送实时性有非常高的要求(关键时候如果指令延时长了,就会损失真金白银),而一路跟着diocp1走到现在diocp3稳定一年多了 ,各方面的表现完全满足需求。

公司名称:

某金融投资公司

DIOCP版本:

从diocp1到DIOCP3 <自定义的编码器>

QQ昵称:

五毒公主(782834)

建议与问题:

我现在这个还只是一个非常小规模的应用,但是有不同的客户端(指令控制端、管理员端、交易终端)会登录到系统,在不同的客户端多了以后 协议就会多很多。 现在是在在一个编码解码器上按命令字来区分再进行业务层的解析。 虽然能满足需求。但是总觉得 如果要做非常庞大和复杂的系统的话 ,协议的管理将非常麻烦。 所以觉得如果可以一个服务器开放多个端口,每个端口有自己的在线列表,不同的客户端登录到不同的端口、应用不同的编码解码器,同时又能统一管理(应为不同的客户端之前需要数据交、转发)这样就是极好的。

 

==========================================

DIOCP官方社区|MyBean官方社区

http://diocp.wedelphi.com/

==========================================

【MyBean调试笔记】接口的使用和清理

【DEMO信息】

有问题的DEMO, 由芒果提交

【问题描述】

双击Tab页面关闭页面和插件的时候出现AV异常

image

【问题调试】

我们在调试的时候出现这个错误时断点停在这里

image

可以看到停留在这个位置@IntfClear,指针清理的位置

image

好我们来调试下这个过程,跟一下是什么时候出现的, 在end 处下个断点后切换到cpu页,我们看到在ret之前调用了一过程,这个地址应该是做一些清理工作后然后返回到调用者地址,

`TDZCGURW[(RGU7B72)5CNY

跟进去后,一会就跳到错误的界面,可以说明在清理时出现的,这个时候我们来看看这段代码

复制代码

procedure TfrmMain.pgcMainMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  Index: Integer;
  lvPluginForm: IPluginForm;
  lvTabShtEx:TTabShtEx;
begin
  // 左键点击并且双击
  if (Button = mbLeft) and (ssDouble in Shift) then
  begin
    Index := pgcMain.IndexOfTabAt(X, Y);
    if Index >= 0 then
    begin
      lvTabShtEx := TTabShtEx(pgcMain.Pages[Index]);
      lvPluginForm := lvTabShtEx.PluginForm;
      if Application.MessageBox('确认要关闭画面吗?', '询问', MB_OKCANCEL + MB_ICONQUESTION) = IDCANCEL then
        Exit;
      lvPluginForm.freeObject;
      pgcMain.Pages[Index].Free;
    end;
  end;
end;

复制代码

这段代码中有一个lvPluginForm为接口IPluginForm变量, 过程在退出时会执行lvPluginForm := nil和其他一些资源的清理工作,清理的时候会触发对象的__release方法,但是我们看到这个对象已经释放掉了,然后在进行清理的时候出现了上面看到的访问违规的错误。

【问题解决】

找到出现问题的根本,解决起来就很快了,尽量不要等到过程清理时在去清理你的资源,特别是可能访问不存在的资源。在end;之前 加一句lvPluginForm := nil;这样就好了

分类: [MyBean说明书]