在system.classes单元中,CheckSynchronize在ThreadLock上持续调用TMonitor的Exit和Enter以保护SyncList。

因为代码做的第一件事是换出SyncList,并且由于对SyncList的所有其他访问也受到ThreadLock上的TMonitor的保护,这只是不必要的代码,增加了锁争用的可能性。

TMonitor.Enter(ThreadLock);

try
Pointer(LocalSyncList) := AtomicExchange(Pointer(SyncList), Pointer(LocalSyncList));
try
Result := (LocalSyncList <> nil) and (LocalSyncList.Count > 0);
if Result then
begin
while LocalSyncList.Count > 0 do
begin
SyncProc := LocalSyncList[0];
LocalSyncList.Delete(0);
TMonitor.Exit(ThreadLock);
try
try
if Assigned(SyncProc.SyncRec.FMethod) then
SyncProc.SyncRec.FMethod()
else if Assigned(SyncProc.SyncRec.FProcedure) then
SyncProc.SyncRec.FProcedure();
except
if not SyncProc.Queued then
SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject
else if Assigned(ApplicationHandleException) then
ApplicationHandleException(SyncProc.SyncRec.FThread);
end;
finally
SyncProc.SyncRec.FThread := nil;
TMonitor.Enter(ThreadLock);
end;
if not SyncProc.Queued then
TMonitor.Pulse(SyncProc.Signal)
else
begin
Dispose(SyncProc.SyncRec);
Dispose(SyncProc);
end;
end;
end;
finally
LocalSyncList.Free;
end;
finally
TMonitor.Exit(ThreadLock);
end;
用下面代码替换:
TMonitor.Enter(ThreadLock);

try
Pointer(LocalSyncList) := AtomicExchange(Pointer(SyncList), Pointer(LocalSyncList));
finally
TMonitor.Exit(ThreadLock);
end;

try
Result := (LocalSyncList <> nil) and (LocalSyncList.Count > 0);
if Result then
begin
while LocalSyncList.Count > 0 do
begin
SyncProc := LocalSyncList[0];
LocalSyncList.Delete(0);
try
try
if Assigned(SyncProc.SyncRec.FMethod) then
SyncProc.SyncRec.FMethod()
else if Assigned(SyncProc.SyncRec.FProcedure) then
SyncProc.SyncRec.FProcedure();
except
if not SyncProc.Queued then
SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject
else if Assigned(ApplicationHandleException) then
ApplicationHandleException(SyncProc.SyncRec.FThread);
end;
finally
SyncProc.SyncRec.FThread := nil;
end;
if not SyncProc.Queued then
TMonitor.Pulse(SyncProc.Signal)
else
begin
Dispose(SyncProc.SyncRec);
Dispose(SyncProc);
end;
end;
end;
finally
LocalSyncList.Free;
end;
https://quality.embarcadero.com/browse/RSP-16353

http://blog.sina.com.cn/s/blog_44fa172f0102wcsp.html

CheckSynchronize实现的不必要的复杂的更多相关文章

  1. Total Commander 8.52 Beta 1

    Total Commander 8.52 Beta 1http://www.ghisler.com/852_b1.php 10.08.15 Release Total Commander 8.52 b ...

  2. Delphi Dll 消息处理

    转载:http://blog.csdn.net/lailai186/article/details/8770643 事情的导火线是GIF图片的显示. 在应用程序中, 利用三方的GIFImage.pas ...

  3. Delphi中线程类TThread实现多线程编程2---事件、临界区、Synchronize、WaitFor……

    接着上文介绍TThread. 现在开始说明 Synchronize和WaitFor 但是在介绍这两个函数之前,需要先介绍另外两个线程同步技术:事件和临界区 事件(Event) 事件(Event)与De ...

  4. Delphi线程基础知识

    参考http://blog.chinaunix.net/uid-10535208-id-2949323.html 一.概述 Delphi提供了好几种对象以方便进行多线程编程.多线程应用程序有以下几方面 ...

  5. Synchronization in Delphi TThread class : Synchronize, Queue

    http://embarcadero.newsgroups.archived.at/public.delphi.rtl/201112/1112035763.html > Hi,>> ...

  6. Delphi组件indy 10中IdTCPServer修正及SSL使用心得

    indy 10终于随着Delphi2005发布了,不过indy套件在我的印象中总是复杂并且BUG不断,说实话,不是看在他一整套组件的面子上,我还是喜欢VCL原生的Socket组件,简洁,清晰.Indy ...

  7. DLL ActiveForm 线程同步问题

    本文试着从分析Synchronize同步执行的实现机制入手,来解决DLL/ActiveForm中线程同步的问题. 线程中进行同步时调用的Synchronize函数,仅仅是把调用调用线程.调用方法地址. ...

  8. Dll方式的线程,需要引用这个

    {== D6DLLSynchronizer =================================================} {: This unit handles the D6 ...

  9. WM_ERASEBKGND官方解释(翻译),以及Delphi里所有的使用情况(就是绘制窗口控件背景色,并阻止进一步传递消息)

    #define WM_ERASEBKGND                   0x0014 Parameters wParam A handle to the device context. //  ...

随机推荐

  1. JVM调优之Tomcat启动参数配置及详解

    开发项目中会遇到Tomcat内存溢出(java.lang.OutOfMemoryError: PermGen space)的问题,通过查找资料找到是通过设置Tomcat 启动堆空间大小.年轻代大小.每 ...

  2. Windows下快速搭建安卓开发环境android-studio

    Windows下快速搭建安卓开发环境android-studio 发布时间:2018-01-18 来源:网络 上传者:用户 关键字: 安卓 搭建 Android Windows 快速 环境 Studi ...

  3. oracle的number的浅析

    author:skate time:2011-02-14 oracle的number的浅析 从例如以下几个方面来认识number 1.表示的数值范围   2.占用的存储空间   3.number的性能 ...

  4. WPF动态加载3D 放大-旋转-平移

    第一步:新建WavefrontObjLoader.cs using System; using System.Collections.Generic; using System.Windows; us ...

  5. EPI_H/EPI_V(边缘保持指数,matlab 矢量化编程)

    EPI: edge preservation index,衡量对原始图像的操作(目标图像)对图像边缘的保持能力. EPI_H:horizontal ,水平方向: EPI_V:vertical,垂直方向 ...

  6. WPF利用HelixToolKit后台导入3D模型

    原文:WPF利用HelixToolKit后台导入3D模型 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/m0_37591671/article/de ...

  7. WPF使用MediaElement显示gif图片

    原文:WPF使用MediaElement显示gif图片 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/SANYUNI/article/details ...

  8. Shell脚本入门学习笔记

    1.shell操作系统和用户之间.负责解释命令行 2./etc/shells 记录登录系统有效支持shell 3./etc/passwd 最后,有人谁可以看到用户的默认shell 4.直接输入shel ...

  9. C#(WPF)为Grid添加实线边框。

    原文:C#(WPF)为Grid添加实线边框. 相信大家在做WPF项目的时候,都会用到Grid这个布局控件,一般情况下,如果只是为了布局,那就不需要显示它的边框,但是也有特殊需求,如果把它当做表格来使用 ...

  10. WPF三维图形

    原文:WPF三维图形 wpf 三维图形基础生成三维图形的基本思想是能得到一个物体的三维立体模型(model).由于我们的屏幕只有二维,因而我们定义了一个用于给物体拍照的照相机(Camera).拍到的照 ...