multithreading - 无法销毁线程中的 THTTPReqResp 组件

标签 multithreading delphi soap delphi-xe

我在从线程的 XE/XE2 中使用 SOAP 时遇到问题。 (我没有使用较旧的 Delphis 对其进行测试。)在主线程中工作的简单代码在使用 无效指针操作 销毁 THTTPReqResp 实例时崩溃。

这是完整的程序。该表单仅包含一个触发 btnTestClick 事件的按钮:

unit Unit79;

interface

uses
  SysUtils, Forms, Classes, Controls, StdCtrls, ComObj,
  ActiveX, InvokeRegistry, SOAPHTTPTrans, Rio, SOAPHTTPClient;

type
  TForm79 = class(TForm)
    btnTest: TButton;
    procedure btnTestClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form79: TForm79;

implementation

{$R *.dfm}

procedure TForm79.btnTestClick(Sender: TObject);
begin
  TThread.CreateAnonymousThread(
    procedure
    var
      FHTTPReqResp: THTTPReqResp;
      FHTTPRIO: THTTPRIO;
    begin
      if CoInitializeEx(NIL, COINIT_MULTITHREADED or COINIT_SPEED_OVER_MEMORY) = S_OK then try
        FHTTPReqResp := THTTPReqResp.Create(nil);
        with FHTTPReqResp do begin
          Name := 'HTTPReqResp1';
          UseUTF8InHeader := True;
          InvokeOptions := [soIgnoreInvalidCerts, soAutoCheckAccessPointViaUDDI];
          WebNodeOptions := [];
        end;
        FHTTPRIO := THTTPRIO.Create(nil);
        with FHTTPRIO do begin
          Name := 'HTTPRIO1';
          HTTPWebNode := FHTTPReqResp;
        end;
        //
        FreeAndNil(FHTTPRIO);
        FreeAndNil(FHTTPReqResp); //<-- crashes here
      finally CoUninitialize; end;
    end
  ).Start;
end;

end.

在 _FreeMem 调用的 TObject.FreeInstance 中引发异常。

procedure TObject.FreeInstance;
begin
  CleanupInstance;
  _FreeMem(Self);
end;

导致此问题的调用堆栈是

:75bab9bc KERNELBASE.RaiseException + 0x58 System.TObject.FreeInstance
System.ErrorAt(2,$4052E1) System.Error(reInvalidPtr)
System.TObject.FreeInstance System._ClassDestroy(???)
Soap.SOAPHTTPTrans.THTTPReqResp.Destroy System.TObject.Free
frmMain.TMainForm.btnTestClick$4934$ActRec.$0$Body
System.Classes.TAnonymousThread.Execute
System.Classes.ThreadProc($F83530) System.ThreadWrapper($F51050)
:76a4339a kernel32.BaseThreadInitThunk + 0x12 :77b59ef2
ntdll.RtlInitializeExceptionChain + 0x63 :77b59ec5
ntdll.RtlInitializeExceptionChain + 0x36

我完全不知道发生了什么,为什么调用 _ClassDestroy 以及为什么代码崩溃:(有人可以 a) 解释我做错了什么 b) 修复我的代码吗?

最佳答案

“无效的指针操作”意味着您正在释放不代表有效内存的内容。这有时可能表明堆栈或堆损坏,但更有可能表明您正在释放已经释放的内容。

毫不奇怪_ClassDestroy叫做。 FHTTPReqResp是非空的,所以当 FreeAndNil来电 Free就在上面,Free来电 Destroy .

看来您的THTTPRIO对象获得 THTTPReqResp 的所有权你给它。如果是这种情况,那么解决方案很简单:不要自己释放它。

关于multithreading - 无法销毁线程中的 THTTPReqResp 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8885455/

相关文章:

c - 如何在 C 中编写线程安全、高效、无锁的内存分配器?

ios - 在手势识别器操作方法中更改 `SKNode` 是否安全?

ios - Magical Record 检测到默认上下文没有变化

delphi - 我可以在Delphi中使用字符串 "IsEmpty"方法吗

java - Java SOAP Web 服务应用程序中的用户登录方法不起作用

node.js - 使用 X509 证书实现 WSSecurity npm 'Soap'

winforms - 具有启动、暂停和停止事件处理的动态线程

delphi - 如何使用纯 GDI 对 Canvas 区域进行颜色混合(按指定的 alpha 值着色)?

delphi - 我可以在Delphi中更改TSavetextfiledialog的保存按钮上的标题吗?

c# - 如何获取 WCF Web 服务请求的 XML SOAP 请求?