Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Delphi: PostThreadMessage & PeekMessage不工作

Delphi: PostThreadMessage & PeekMessage不工作
EN

Stack Overflow用户
提问于 2014-02-10 06:07:39
回答 2查看 2.4K关注 0票数 1

当我的主应用程序(Delphi2009)终止时,我想让它通知我的线程(定时器、带ADO连接的TDataModules、SMTP等)优雅地进行处理。

在我的主应用程序中,我有以下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
try
      PostThreadMessage(bpvccMAILER.ThreadID, WM_SYSTEM_CLOSE, self.Handle, 0);
      returnMessage := (SysErrorMessage(GetLastError)); //Returns 'The operation completed successfully'
    while TRUE do
            begin
                sleep(1000);
                if not (Assigned(bpvccMAILER)) then
                begin
                    bpvccACTIVITY_LOGGER.Write('SHUTDOWN','TBPVCommunicatorGUI.FormClose - All Threads have shut down');
                    break;
                end;
                locWaited := locWaited  + 10;
            end;  
        except
        end;
    finally
        FreeAndNil(bpvccACTIVITY_LOGGER);
        FreeAndNil(bpvccMAILER);
    end;

线程类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
TBPVMailer = class(TThread)
    protected
        SMTP       : TIdSMTP;
        interval   : Integer;
        fMain      : Integer;
        fMainIsSvc : Boolean;
        fTerminated: Boolean;
        function SendEmail(AEmail: TEmailObj) : TBPVEmailSendResult;
        function doSleep : Boolean;
        procedure Write(AStatus, AMessage : String);
        procedure FlushQueue();
        procedure HandleMessage(var Message : TMessage); message WM_SYSTEM_CLOSE;
    public
        constructor Create(AServer : String; APort : Integer; AUser, APass : String; AInterval : Integer; StartSuspended : Boolean); overload;
        procedure   Execute; override;
        procedure QueueEmail(AEmail: TEmailObj; EmailType : TBPVEmailType; AssociatedID : String);
        destructor Destroy; override;
end;

procedure TBPVMailer.HandleMessage(var Message: TMessage);
var
msg : tagMSG;
begin
  PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE);
    fMain := Message.WParam;
    fMainIsSvc := Message.LParam = 1;
    fTerminated := TRUE;
end;

问题是,Assigned(bpvccMAILER)即使在调用PostThreadMessage之后也总是返回true。此外,bpvccMAILER.fTerminated始终为FALSE,这意味着永远不会执行TBPVMailer.HandleMessage,因为此时值被设置为TRUE。我做错了什么,我的线程似乎没有接收到消息?

EN

回答 2

Stack Overflow用户

发布于 2014-02-10 07:17:04

一个显而易见的解释是你的线程中没有消息泵。你发布了消息,但是线程并不抽取它的队列。

不过,代码是不必要的复杂。似乎根本不需要消息。调用线程的Terminate方法,然后使用它的WaitFor方法等待线程停止。或者更简单,只需在线程上调用Free

你的代码确实包含了一些奇怪的东西:

  • 为什么要调用PeekMessage?据我所知,那没有任何用处。应避免使用Sleep等待
  • 。您几乎总是可以使用专用的等待函数。
  • 奇怪的是,你要等到bpvccMAILERnil,然后再使用FreeAndNil(bpvccMAILER)
  • 只有在定义明确时才能调用GetLastError。通常情况下,这仅在前面的API调用失败时才会发生。并且失败由API调用返回的值指示。
票数 4
EN

Stack Overflow用户

发布于 2017-05-10 17:04:38

只需调用PostThreadMessage并返回,之后不会有任何睡眠循环。

如果您需要等到bpvccMAILER完成,可以添加代码,在完成时向主线程发送一个PostMessage。因此,主线程将处理此消息,并将意识到辅助线程已完成。从一开始就以这种方式更改您的应用程序可能并不容易,但渐渐地,您将以这样一种方式设计应用程序,即始终执行正确的线程处理。

除此之外,如果你使用PostThreadMessage,那么你的Thread.Execute循环必须有MsgWaitForMultipleObjects。

下面是一个关于Thread.Execute循环的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<skipped>
repeat
  <skipped>
  R := MsgWaitForMultipleObjects(EventCount, EventArray, False, INFINITE, QS_ALLINPUT);
  <skipped>
  if R = WAIT_OBJECT_0 + EventCount then
  begin
    while PeekMessage(M, 0, 0, 0, PM_REMOVE) do
    begin
      if M.Message = WM_QUIT then
        Break;
      TranslateMessage(M);
      DispatchMessage(M);
    end;
    if M.Message = WM_QUIT then
      Break;
  end;
  <skipped>
until Terminated;
<skipped>

如果应用程序最终需要在踏步运行时退出(假设线程对象在T变量中),请执行以下操作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
T.Terminate;
SetEvent([one of the event of the EventArray]); // we should call it AFTER terminate for the Terminated property would already be True when the tread exits from MsgWaitForMultipleObjects
T.WaitFor; 
T.Free; // "Free" calls "WaitFor" anyway, but Remy Lebeau suggests to explicitly call "WaitFor" before "Free".
T := nil;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21670162

复制
相关文章
更改Linux终端颜色主题【Linux-Command line】
如果你一整天都盯着终端,自然想让它变得赏心悦目。 对美的判断因人而异,自CRT串行控制台问世以来,终端已经走了很长一段路。 因此,很有可能你的软件终端窗口中有很多选项可以使你看到的内容主题化,不管你如何定义美。
QRosie
2019/11/24
9K0
更改Linux终端颜色主题【Linux-Command line】
颜色、网页颜色与网页安全色
我们所看到的屏幕上所有的颜色都是由红、绿、蓝这三种基色调混合而成的。(在印刷上,颜色是四种颜色合成的,这个是表示方式上的不同。)每一种颜色的饱和度和透明度都是可以变化的,用0~255的数值来表示。如纯红色表示为(255,0,0),十六进制表示为#FF0000。按这种表达方式,理论上我们可以得到256*256*256=16777216种颜色。
大江小浪
2018/07/25
3.5K0
颜色、网页颜色与网页安全色
更改网页的标签
以Safari浏览器、百度主页为例子 先上效果对比图: 效果图.png 原图.png 好了,现在开始搞过程: ️:打开Safari浏览器,进入www.baidu.com;然后鼠标右键选择-检查元素
且行且珍惜_iOS
2018/05/22
1.3K0
Jupyter Notebook 更改主题
Customize your Jupyter Notebook Theme in 2 lines of code
莫听穿林
2022/02/16
8200
Jupyter Notebook 更改主题
如何更改 Ubuntu 的终端的颜色
但是,如果你想要一个独一无二的的终端体验或者符合你自身品位的一些东西,你也可以改变你的 Ubuntu 的终端的颜色。
用户1880875
2021/11/08
14.5K0
更改WordPress主题全局字体
加入以下自定义CSS即可 /* 您可以在此处加入您的CSS。 点击上方的帮助图标来了解更多。 */ /*字体设定*/ *:not([class*="icon"]):not(i) { font-family: "Helvetica Neue", "Luxi Sans", "DejaVu Sans", Tahoma, "Hiragino Sans GB", "Microsoft Yahei", sans-serif !important; } /*字体阴影*/ *{text-shadow: 0
回忆大大
2021/08/09
1.2K0
更改WordPress主题全局字体
pycharm 风格_python主题更改
下载好的插件是一个zip文件,在pycharm的Plugins栏中选择install plugins from disk,选择插件后重启即可
全栈程序员站长
2022/09/27
7680
pycharm 风格_python主题更改
还有哈利波特主题的颜色包!?是时候汇总Python-R的颜色主题包了
今天这篇推文我们系统介绍下颜色主题,虽然之前也有介绍过一些优秀的配色网站,也有搭配好的颜色主题可以直接参考,但有没有直接供Python或者R绘图直接使用的关于颜色设置的第三方包呢?这边推文将较为详细的介绍关于Python的R的颜色主题包,主要涉及的内容如下:
DataCharm
2021/02/22
1.2K0
还有哈利波特主题的颜色包!?是时候汇总Python-R的颜色主题包了
Black Vendetta -改变主题颜色
其实不是很喜欢换主题每次换主题都会需要折腾很多的后续问题。虽然这个主题和上个主题是从同一个模板修改过来的。但是鉴于Artisteer 4不能直接编辑css文件,每次修改完了都需要重新调校很多的东西,所以换主题就成了一件很蛋疼的事情,并且有很多功能都是通过修改主题生成的php文件直接得到的。
obaby
2023/02/23
5220
idea 怎么换主题,如何换主题颜色
直接上步骤 直接搜索: Appearance 也可以 颜色 根据你自己来
用户9006224
2022/12/21
2.2K0
idea 怎么换主题,如何换主题颜色
[踩坑]iconfont Symbol svg引入无法更改颜色
最近公司组织架构调整(反正每次组织架构调整,领导就会下场。有一个idea或者有重构一下,先定一个月底上),被拉取一个项目组做新项目。这边图标现状:有些项目是font-face方式,有些用的阿里图标库,最近又在用腾讯图标库,有些甚至直接切图。
玖柒的小窝
2021/11/16
3.7K0
[踩坑]iconfont Symbol svg引入无法更改颜色
keil更改黑色背景颜色「建议收藏」
1、先将keil安装目录下UV4中global文件复制出来留作备用,然后用记事本打开安装目录下的global文件
全栈程序员站长
2022/09/10
7.6K0
keil更改黑色背景颜色「建议收藏」
网页设计的12种颜色
他们发现,美国前100大网站的Logo,主要使用12种颜色。其中,采用蓝色的网站最多,红色排在第二种,黄色排在第三种。
ruanyf
2018/09/21
9020
网页设计的12种颜色
office颜色配置技巧与自定义颜色主题
上一篇给大家介绍了基础的色彩知识,今天要跟大家简单介绍一下office(office系列所有套件的调色板是通用的)办公软件的内置色板的使用技巧以及如何自定义颜色主题。 ▼▼▼▼▼ 因为微软从office2007版开始,启用了新的内置色板样式并增加了可编辑颜色数量,考虑到03版已经不再普及,今天就以office2010版为例给大家讲解(office2007与2013与2016同样适用)。 新的颜色面板提供了70个格子,如下图所示。第一行是基本色,之后的五行由第一行变化而来。 再之后是1行所谓的标准色和一个“其
数据小磨坊
2018/04/03
2.5K0
office颜色配置技巧与自定义颜色主题
MDUI CSS框架 ---颜色和主题
背景颜色类名为 .mdui-color-[color]-[degree]。它在设置背景色的同时,还设置了背景色中的文本颜色和文本不透明度。
meowrain
2021/04/22
1.7K0
MDUI CSS框架 ---颜色和主题
Android系统更改状态栏字体颜色
原文地址:http://blog.isming.me/2016/01/09/chang-android-statusbar-text-color/,转载请注明出处。 随着时代的发展,Android的状态栏都不是乌黑一片了,在Android4.4之后我们可以修改状态栏的颜色或者让我们自己的View延伸到状态栏下面。我们可以进行更多的定制化了,然而有的时候我们使用的是淡色的颜色比如白色,由于状态栏上面的文字为白色,这样的话状态栏上面的文字就无法看清了。因此本文提供一些解决方案,可以是MIUI6+,Flyme4+
非著名程序员
2018/02/02
2.4K0
SecureCRT更改vim中#注释的文本内容颜色
今天在学习redis的时候,发现vim打开redis.conf配置文件的时候,#注释起来的代码是蓝色的,阅读起来很不方便。
上分如喝水
2021/08/16
6.2K0
SecureCRT更改vim中#注释的文本内容颜色
点击加载更多

相似问题

更改网页主题

23

更改代码颜色主题中的颜色

22

更改主题轮廓颜色

10

根据Windows主题更改面板的主题(颜色)

32

从Eclipse颜色主题更改主题中的突出显示颜色

22
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文