- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个程序,它使用多个线程来执行某些任务。每个线程都有一堆任务要执行。执行其中之一后,每个线程都会向主屏幕调用一个发布消息以更新日志。
现在我有六万个任务,每个线程一万个 - 六个线程 - 在执行每个任务线程之后调用发布消息。但是由于这些帖子消息,我的应用程序变得非常繁忙,看起来像是挂了。
如果我删除帖子消息...一切正常。但是我不能直接调用该过程,因为它使用 ui 控件并且 ui 控件不是线程安全的,直接从线程调用过程会导致其他错误。
那么是否有任何替代方法可用于 postmessage 和 send message。
谢谢,
罗勒
最佳答案
问题是发布的消息有两个消息队列。这样做的结果是您发布的消息是 always processed before any Paint
, Input
, or Timer
messages.
这意味着您正在用几十万条消息充斥消息队列。这些消息将始终在绘制和用户消息之前得到处理 - 使您的应用程序看起来挂起。
解决这个问题的常用方法是使用定时器;让您的代码启动一个非常短的持续时间(例如 0 毫秒)计时器。
Clarification
Timer messages (
WM_TIMER
), like Paint messages (WM_PAINT
) and Input messages (e.g. WM_MOUSEMOVE, WM_KEYDOWN) are processed after posted messages. Timer messages specifically are processed after input and paint messages.This means that your application will respond to user events and paint requests before it handles the next
WM_TIMER
message. You can harness this behavior by using a Timer (and it'sWM_TIMER
message), rather than posting a message yourself (which would always take priority over paint and input messages).
WM_TIMER
信息。此消息将始终在任何输入和绘制消息之后处理;使您的应用程序看起来响应迅速。
...messages are processed in the following order:
//Code is public domain. No attribution required.
const
WM_ProcessNextItem = WM_APP+3;
procedure WindowProc(var Message: TMessage)
begin
case Message.Msg of
WM_Paint: PaintControl(g_dc);
WM_ProcessNextItem:
begin
ProcessNextItem();
Self.Invalidate; //Invalidate ourselves to trigger a wm_paint
//Post a message to ourselves so that we process the next
//item after any paints and mouse/keyboard/close/quit messages
//have been handled
PostMessage(g_dc, WM_ProcessNextItem, 0, 0);
end;
else
DefWindowProc(g_dc, Message.Msg, Message.wParam, Message.lParam);
end;
end;
WM_ProcessNextItem
在我生成
WM_PAINT
之后消息(即
Invalidate
),
WM_PAINT
永远不会被处理,因为在它之前总会有另一条发布的消息。和
as MSDN says ,仅当没有其他发布的消息时才会显示绘制消息。
Sent and posted messages
The terminology I will use here is nonstandard, but I'm using it because I think it's a little clearer than the standard terminology. For the purpose of this discussion, I'm going to say that the messages associated with a thread fall into three buckets rather than the more standard two:
What I'll call them Standard terminology
=========================== =============================
Incoming sent messages Non-queued messages
Posted messages \_
Input messages / Queued messagesIn reality, the message breakdown is more complicated than this, but we'll stick to the above model for now, because it's "true enough."
This is a simplification of what actually goes on, but it's close enough for the purposes of this discussion.
WM_MOUSEMOVE
) WM_LBUTTONDOWN
) WM_LBUTTONUP
) WM_PAINT
) WM_ProcessNextItem
) GetMessage
)不会按照消息发生的顺序接收消息。它将检索
WM_ProcessNextItem
信息。这将从队列中删除消息,留下:
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_PAINT
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_PAINT
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_ProcessNextItem
你向自己发回另一条消息。您这样做是因为您想先处理未完成的消息,然后再继续处理更多项目。这会将另一条已发布的消息添加到队列中:
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_PAINT
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_ProcessNextItem
GetMessage
将检索
WM_ProcessNextItem
,让应用程序留下大量的绘制和输入消息:
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_PAINT
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_MOUSEMOVE
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
Posted messages Input messages
================== =====================
WM_ProcessNextItem WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_PAINT
WM_TIMER
信息:
Posted messages Input messages
================== =====================
WM_MOUSEMOVE
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_PAINT
WM_TIMER
Nitpickers Corner: This description of two queues isn't strictly true, but it's true enough. How Windows delivers messages in the documented order is an internal implementation detail, subject to change at any time.
WM_TIMER
的机制。信息。你这样做是因为你知道
定时器 消息的优先级不会高于
油漆或
输入 消息。
WM_PAINT
,
WM_TIMER
和输入消息,它们也有乱序处理:
WM_PAINT
,然后 WM_TIMER
关于delphi - Postmessage 和 sendmessage 的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7616591/
我应该编写一个函数来打印一组给定的三个数字中两个较大数字的平方和。 我对这种情况的处理相当笨拙。我没有编写返回一组 3 中最大的两个数字的函数,而是编写了函数,以便表达式减少到两个所需的数字。 # S
如果有人可以提供帮助,我将不胜感激。我一直在敲我的头一天试图让这个工作。我已经在互联网上搜索并重新阅读了手册,但我就是不明白。 guile << __EOF__ ( define heading-li
目前我正在处理一个方案问题,其中我们正在使用方案列表表示一个图。我们使用的第一个变体是表示为 的边列表图 '((x y) (y z) (x z)) 我们正在使用的图的第二个变体被称为 x 图,表示为
我正在尝试创建一个函数,该函数将两个函数作为参数并执行它们。 我尝试使用 cond ,但它只执行 action1 . (define seq-action (lambda (action1 act
我提前为我的原始英语道歉;我会尽量避免语法错误等。 两周前,我决定更新我对 Scheme(及其启示)的知识,同时实现我在手上获得的一些数学 Material ,特别是我注册的自动机理论和计算类(cla
Scheme中有没有函数支持分数的“div”操作? 意思是 - 11 格 2.75 = 4。 最佳答案 我认为你的问题的答案是:没有,但你可以定义它: #lang racket (define (di
我在scheme中实现合并排序,我必须通过定义两个辅助方法来实现:merge和split。 Merge 需要两个列表(已经按递增顺序)并将它们合并在一起。我这样做了如下: (define merge
尝试从终端加载方案文件。我创建了一个名为 test.scm 的文件,其中包含以下代码: (define (square x) (* x x)) (define (sum-of-squares x y)
我有以下代码: (define (howMany list) (if (null? list) 0 (+ 1 (howMany (cdr list))))) 如果我们执行以
我有点了解如何将基本函数(例如算术)转换为Scheme中的连续传递样式。 但如果函数涉及递归怎么办?例如, (define funname (lambda (arg0 arg1)
我正在尝试附加两个字符串列表 但我不知道如何在两个单词之间添加空格。 (define (string-concat lst1 lst2) (map string-append lst1
这个问题已经有答案了: How do I pass a list as a list of arguments in racket? (2 个回答) 已关闭 8 年前。 我有一个函数,它需要无限数量的
我对这段代码的工作方式感到困惑: (define m (list 1 2 3 '(5 8))) (let ((l (cdr m))) (set! l '(28 88))) ==>(1 2 3 (5 8
我正在为学校做一项计划作业,有一个问题涉及我们定义记录“类型”(作为列表实现)(代表音乐记录)。 我遇到的问题是我被要求创建一个过程来创建这些记录的列表,然后创建一个将记录添加到该列表的函数。这很简单
我有以下代码: (define (howMany list) (if (null? list) 0 (+ 1 (howMany (cdr list))))) 如果我们执行以
我正在尝试附加两个字符串列表 但我不知道如何在两个单词之间添加空格。 (define (string-concat lst1 lst2) (map string-append lst1
如何使用抽象列表函数(foldr、foldl、map 和 filter 编写函数),无需递归,消耗数字列表 (list a1 a2 a3 ...) 并产生交替和 a1 - a2 + a3 ...? 最
我试图找出在 Scheme 中发生的一些有趣的事情: (define last-pair (lambda (x) (if (null? (cdr x))
这个问题在这里已经有了答案: Count occurrence of element in a list in Scheme? (4 个答案) 关闭 8 年前。 我想实现一个函数来计算列表中元素出现
我正在尝试使用下面的代码获取方案中的导数。谁能告诉我哪里出错了?我已经尝试了一段时间了。 (define d3 (λ (e) (cond ((number? e) 0) ((e
我是一名优秀的程序员,十分优秀!