multithreading - 在 TThread.Execute 中调用 TDataModule 方法

标签 multithreading delphi datamodule

一般来说,在 TThread.Execute 过程中是否可能 调用 TDataModule 方法,其中不涉及视觉事件?

谢谢大家,马西莫。

最佳答案

最简单的方法是使用 TThread.Synchronize 调用数据模块中的方法。

但是,如果您不想这样做,即使不涉及任何视觉事件,您也应该确定是否需要添加 critical section为了保护你。

对任何标准或第三方 VCL 组件的任何访问,无论是可视的(TButton)还是非可视的(数据集)都应被视为不安全。对本地数据对象(如私有(private)字段或全局变量)的任何访问也必须受到关键部分的保护。

这是从后台线程到数据模块的直接调用:

    if Assigned(MyDataModule) then MyDataModule.DoSomething(a,b,c);

这是数据模块中的代码,我向您展示了一段示例代码,以确保我们是目前唯一接触 FList 的线程:

/// DoSomething: Note this method must be thread-safe!
procedure TMyDataModule.DoSomething(a:TMyObject1;b:TMyObject2;c:TMyObject3);
begin
   FCriticalSection.Enter;
   try
     if not FList.Contains(a) then
       FList.Add(a); 
     ...
   finally
   FCriticalSection.Leave;
   end;
end;

/// elsewhere in the same data module, wherever anybody modifies or checks the state 
/// (content) of FList, wrap the method with a critical section like this:
function TMyDataModule.HasItem(a:TMyObject1):Boolean;
begin
   FCriticalSection.Enter;
   try
     result := FList.Contains(a); 
   finally
     FCriticalSection.Leave;
   end;
end;

Delphi 多线程编程的一些入门规则简而言之是:

  • 不要做任何可能造成竞争条件的事情。
  • 每当您访问类(数据模块)或任何全局变量中的任何数据字段时,请不要忘记使用关键部分、互斥体等同步原语,以防止并发问题(包括竞争条件)。如果使用不当,就会在问题列表中添加死锁。所以这不是一个搞砸的好地方。
  • 如果您必须以任何方式访问 VCL 组件或对象,请通过 PostMessage、TThread.Synchronize 或其他一些线程安全的等效方式来间接执行此操作,以向主线程发出您需要完成某些操作的信号。
    • 想想当你关机时会发生什么。也许您可以在调用其方法之前检查您的数据模块是否存在,因为它可能已经消失。

关于multithreading - 在 TThread.Execute 中调用 TDataModule 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2357024/

相关文章:

java - 使用多线程时打开和关闭数据库连接

delphi - 在 Delphi 中设置 DBGrid 列格式

delphi - 调试断点仅在DataModule单元中不起作用-Delphi

database - 使用 delphi 的 Dll 中的数据模块?

c# - 如何在 C# 中向线程添加函数?

python - 当子类化 threading.Thread 时,我是否必须调用 super.join() ?

c++ - Microsoft Detours - DetourUpdateThread?

delphi - 我自己的存储和检索使用 Delphi 文本 DFM 格式的生命周期很长

forms - 模态表格不会关闭

Delphi - 如何向 TDataModule 发送 Windows 消息?