加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 断开连接时的IdHTTP访问冲突

发布时间:2020-12-15 09:29:55 所属栏目:大数据 来源:网络整理
导读:Indy 10: 两个线程,线程1在TIdHTTP上调用Get并阻止读取数据. 线程2将在同一TIdHTTP上调用disconnect以中断Get. 我在TIdHTTP上使用摘要式身份验证,我偶尔会得到一个AV. 线程1的callstack: 40491D [system.pas][System][@ClassDestroy][8989]69EF2B [....c
Indy 10:

两个线程,线程1在TIdHTTP上调用Get并阻止读取数据.
线程2将在同一TIdHTTP上调用disconnect以中断Get.

我在TIdHTTP上使用摘要式身份验证,我偶尔会得到一个AV.

线程1的callstack:

40491D [system.pas][System][@ClassDestroy][8989]
69EF2B [....commonIdAuthenticationDigest.pas][IdAuthenticationDigest][TIdDigestAuthentication.Destroy][109]
404567 [system.pas][System][TObject.Free][8313]
6A2B69 [....CommonIdHTTP.pas][IdHTTP][TIdCustomHTTP.DoOnDisconnected][1587]
534574 [IdTCPConnection.pas][IdTCPConnection][TIdTCPConnection.Disconnect][532]
534B3B [IdTCPConnection.pas][IdTCPConnection][TIdTCPConnection.Disconnect][767]
6A3FB3 [....CommonIdHTTP.pas][IdHTTP][TIdCustomHTTP.DoRequest][2101]

线程2的callstack:

402BA3 [system.pas][System][@FreeMem][2477]
404521 [system.pas][System][TObject.FreeInstance][8294]
40491D [system.pas][System][@ClassDestroy][8989]
69EF2B [....commonIdAuthenticationDigest.pas][IdAuthenticationDigest]        [TIdDigestAuthentication.Destroy][109]
404567 [system.pas][System][TObject.Free][8313]
6A2B69 [....CommonIdHTTP.pas][IdHTTP][TIdCustomHTTP.DoOnDisconnected][1587]
534574 [IdTCPConnection.pas][IdTCPConnection][TIdTCPConnection.Disconnect][532]
534B3B [IdTCPConnection.pas][IdTCPConnection][TIdTCPConnection.Disconnect][767]

基本上在DoRequest结束时它会断开连接.似乎在尝试释放Request.Authentication的断开连接上存在竞争条件.

下载了Indy 10的最新代码并查看代码,我相信行为应该是相同的.

我相信从另一个线程断开调用是推荐的使用模式,我错了吗?这是Indy的一个错误吗?似乎有必要锁定断开连接,但很难看到可能造成的死锁.还有其他人遇到过这个吗?

解决方法

是的,您遇到的是竞争条件,两个线程在断开套接字时尝试释放相同的Request.Authentication对象两次.给定堆栈跟踪,两个线程必须在完全相同的时间断开套接字,因为如果IOHandler仍然打开,Disconnect()仅调用DoOnDisconnect(),并且在调用DoOnDisconnect()之前关闭IOHandler.

您可以尝试执行的操作是使用OnStatus事件在hsDisconnecting状态中输入线程安全锁,例如临界区或互斥锁,并将锁保留在hsDisconnected状态.在这些状态之间调用IOHandler.Close()和DoOnDisconnect(),这样就可以有效地序列化线程,这样它们就不能断开套接字并在同一时间释放Request.Authentication对象.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读