- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个问题,与正常应用程序中的相同代码相比,我的 dll 中的代码的行为有所不同。经过一些调试后,我发现 dll 中从未调用线程的 OnTerminate。
type
TTest = class
private
public
procedure threadStart();
procedure threadEnd(Sender: TObject);
procedure lines(value: String);
end;
procedure TTest.threadStart();
var aThread : TThread;
begin
aThread :=
TThread.CreateAnonymousThread(
procedure
begin
lines('start')
end
);
aThread.FreeOnTerminate := True;
aThread.OnTerminate := self.threadEnd;
aThread.Start;
end;
procedure TTest.threadEnd;
begin
lines('end')
end;
procedure TTest.lines(value: String);
var MyText: TStringlist;
begin
MyText:= TStringlist.create;
MyText.Add(value);
MyText.SaveToFile('.\filename.txt');
MyText.Free
end;
如果我从普通的 VLC Delphi 应用程序运行此代码,我会在文本文件中得到 end 。如果我从 dll 运行相同的代码(将其静态或动态加载到 VLC 应用程序中),我会在文本文件中得到 start 。
我的问题:为什么?或者更好地问,我怎样才能让我的 dll 的行为与我的 VLC 相同。我当前使用的版本是XE7。
最佳答案
TThread.OnTerminate
通过调用 TThread.Synchronize()
在主 UI 线程的上下文中触发事件,它将请求存储在主 UI 线程定期检查的队列中,并在可用时执行挂起的请求。
如果 DLL 和 EXE 是在启用运行时包的情况下编译的,则它们共享 RTL 的单个副本(因此需要您使用应用程序部署 rtl.bpl
)。当 EXE 检查 RTL 的 Synchronize()
时队列中,它将看到来自 EXE 和 DLL 的待处理请求。
但是,如果它们不共享单个 RTL,那么它们将使用彼此不链接的单独 RTL 副本进行编译。默认情况下,EXE 中没有任何内容检查和处理来自 DLL 的 Synchronize()
的待处理请求。队列,仅来自 EXE 的 Synchronize()
队列。为了解决这个问题,您必须从调用 CheckSynchronize()
的 DLL 中导出一个函数。 DLL 的 RTL 函数,然后定期(例如在计时器中)进行导出 DLL 函数的 EXE 调用。
否则,解决此问题的另一种方法是绕过 Synchronize()
触发 OnTerminate
的调用事件,通过覆盖线程的虚拟 DoTerminate()
方法(您不能使用 TThread.CreateAnonymousThread()
来执行此操作)。您可以拥有DoTerminate()
调用OnTerminate
直接,或者只是在 DoTerminate()
中执行您需要的操作本身。但无论哪种方式,您都必须确保此代码是线程安全的,如 DoTerminate()
在工作线程的上下文中运行。
关于delphi - 为什么在 dll 内不调用 threadTerminate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27954162/
我有一个问题,与正常应用程序中的相同代码相比,我的 dll 中的代码的行为有所不同。经过一些调试后,我发现 dll 中从未调用线程的 OnTerminate。 type TTest = class
我是一名优秀的程序员,十分优秀!