在 Delphi 中释放 TCriticalSection 对象的正确方法
Correct way to free TCriticalSection object in Delphi
这是释放 Delphi 初始化部分中创建的 TCriticalSection
对象的正确方法吗?
initialization
FPoolingCS := TCriticalSection.Create;
finalization
FPoolingCS.Acquire;
FreeAndNil(FPoolingCS);
我应该在 Free
之前调用 Release
方法吗?
Acquire
方法会抛出一些我需要处理的异常吗?
由于多种原因,这不是释放临界区的正确方法。
根据文档EnterCriticalSection function
This function can raise EXCEPTION_POSSIBLE_DEADLOCK if a wait
operation on the critical section times out. The timeout interval is
specified by the following registry value:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session
Manager\CriticalSectionTimeout. Do not handle a possible deadlock
exception; instead, debug the application.
If a critical section is deleted while it is still owned, the state of
the threads waiting for ownership of the deleted critical section is
undefined.
While a process is exiting, if a call to EnterCriticalSection would
block, it will instead terminate the process immediately. This may
cause global destructors to not be called.
在 Windows 平台上调用 FPoolingCS.Acquire
调用 EnterCriticalSection
函数。所以第一个问题的答案,获取临界区是否会引发异常,是的。
另外根据文档,您不应尝试处理此类异常,但您必须调试应用程序,因为问题的根源在于其他代码。
但是在任何平台上释放关键部分实例之前不应调用 Acquire
的最值得注意的原因是,如果此时有一些其他线程正在做一些工作并且依赖于该关键部分部分表示您的关机和清洁过程完全中断。换句话说,如果 Acquire
解决了你的问题,真正的问题在另一座城堡里,你并没有真正解决任何问题,你只是稍微改变了动态,这可能有效也可能无效,这取决于所有其他代码涉及。
在 Free
之前调用 Release
将毫无意义,原因相同。如果还有其他涉及的线程仍然 运行,它们可能会在 Free
执行之前获取锁。
只需在关键部分调用 Free
,或者如果您喜欢使用 FreeAndNil
,如果您的关闭过程被破坏,它最终会崩溃。请记住,线程问题并非始终可重现,因此没有崩溃并不意味着您的代码完全没有错误。
这是释放 Delphi 初始化部分中创建的 TCriticalSection
对象的正确方法吗?
initialization
FPoolingCS := TCriticalSection.Create;
finalization
FPoolingCS.Acquire;
FreeAndNil(FPoolingCS);
我应该在 Free
之前调用 Release
方法吗?
Acquire
方法会抛出一些我需要处理的异常吗?
由于多种原因,这不是释放临界区的正确方法。
根据文档EnterCriticalSection function
This function can raise EXCEPTION_POSSIBLE_DEADLOCK if a wait operation on the critical section times out. The timeout interval is specified by the following registry value: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CriticalSectionTimeout. Do not handle a possible deadlock exception; instead, debug the application.
If a critical section is deleted while it is still owned, the state of the threads waiting for ownership of the deleted critical section is undefined.
While a process is exiting, if a call to EnterCriticalSection would block, it will instead terminate the process immediately. This may cause global destructors to not be called.
在 Windows 平台上调用 FPoolingCS.Acquire
调用 EnterCriticalSection
函数。所以第一个问题的答案,获取临界区是否会引发异常,是的。
另外根据文档,您不应尝试处理此类异常,但您必须调试应用程序,因为问题的根源在于其他代码。
但是在任何平台上释放关键部分实例之前不应调用 Acquire
的最值得注意的原因是,如果此时有一些其他线程正在做一些工作并且依赖于该关键部分部分表示您的关机和清洁过程完全中断。换句话说,如果 Acquire
解决了你的问题,真正的问题在另一座城堡里,你并没有真正解决任何问题,你只是稍微改变了动态,这可能有效也可能无效,这取决于所有其他代码涉及。
在 Free
之前调用 Release
将毫无意义,原因相同。如果还有其他涉及的线程仍然 运行,它们可能会在 Free
执行之前获取锁。
只需在关键部分调用 Free
,或者如果您喜欢使用 FreeAndNil
,如果您的关闭过程被破坏,它最终会崩溃。请记住,线程问题并非始终可重现,因此没有崩溃并不意味着您的代码完全没有错误。