如何使用winforms实现消息泵? [英] How can i implement a message pump with winforms ?

查看:65
本文介绍了如何使用winforms实现消息泵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我在一个功能中做了很长时间的治疗,而且我正在显示治疗进展的

带进度条。代码是

这样的:

每个
(条目中的条目)//大约100个条目

{

TreatmentForOneOr2Secs();

this-> progressBar1-> PerformStep();

}
调试期间
,调试器告诉我:


托管调试助手''ContextSwitchDeadlock''已在'd:\ test\NetSendDotNet中检测到

问题\ debug \ NetSendDotNet.exe''。

附加信息:CLR无法从COM上传到上下文0x189558到COM上下文0x189408,持续60秒。拥有目的地上下文/公寓的线程

很可能是在没有抽水等待或处理非常长时间运行的情况下进行

a无需抽水
Windows消息。这种情况通常会对性能产生负面影响,甚至可能会导致应用程序变得非响应或内存使用量不断累积。为了避免这个问题,所有单线程公寓(STA)线程都应该使用

抽等待原语(如CoWaitForMultipleHandles)和

例行泵长时间运行期间的消息。

特别是:

为了避免这个问题,所有单线程单元(STA)线程

应该使用抽取等待原语(例如CoWaitForMultipleHandles)

并且在长时间运行期间定期抽取消息。


那么,我如何抽取消息?或者,我应该使用一个线程(以及如何?)

感谢您的帮助

Nicolas H.

Hi all,

i''m doing a quite long treatment in a function, and i''m showing the
progress of the treatment with a progressbar. The code is something
like this :

for each(entry in entries) // about 100 entries
{
TreatmentForOneOr2Secs();
this->progressBar1->PerformStep();
}
during the debug, the debugger tells me that :

Managed Debugging Assistant ''ContextSwitchDeadlock'' has detected a
problem in ''d:\test\NetSendDotNet\debug\NetSendDotNet.exe''.
Additional Information: The CLR has been unable to transition from COM
context 0x189558 to COM context 0x189408 for 60 seconds. The thread
that owns the destination context/apartment is most likely either doing
a non pumping wait or processing a very long running operation without
pumping Windows messages. This situation generally has a negative
performance impact and may even lead to the application becoming non
responsive or memory usage accumulating continually over time. To avoid
this problem, all single threaded apartment (STA) threads should use
pumping wait primitives (such as CoWaitForMultipleHandles) and
routinely pump messages during long running operations.
Specially :
To avoid this problem, all single threaded apartment (STA) threads
should use pumping wait primitives (such as CoWaitForMultipleHandles)
and routinely pump messages during long running operations.

So, how can i pumping messages ? or, should i use a thread (and how ?)
Thanks for your help
Nicolas H.

推荐答案

>特别是:
为了避免这个问题,所有单线程单元(STA)线程都应该使用抽取等待原语(例如CoWaitForMultipleHandles)<在长时间运行期间定期泵送消息。
那么,我怎么能抽信息呢?或者,我应该使用一个线程(以及如何使用?)
To avoid this problem, all single threaded apartment (STA) threads
should use pumping wait primitives (such as CoWaitForMultipleHandles)
and routinely pump messages during long running operations. So, how can i pumping messages ? or, should i use a thread (and how ?)




更优雅的解决方案可能是使用计时器。

每次过去计时器事件,处理一个工作项。这将使您的

应用程序有机会在您自己的处理之间执行附加消息处理。


这也意味着你的整体处理时间会更长,因为你没有继续处理你自己的东西。

使用一个单独的线程会给你更好的性能,但需要

更多编码。


在消息处理程序中抽取消息是我从未尝试过的事情

..NET,所以我不喜欢不知道是否可能。


亲切的问候,

布鲁诺。
BR ********************** @ hotmail.com

仅删除_nos_pam



A more elegant solution perhaps is to use a timer.
on each elapsed timer event, process one work item. this will give your
application the chance to perform aditional message processing in between
your own processing.

this also means that your overall processing will take longer, since you are
not continuously processing your own stuff.
using a separate thread will give you a bit better performance,but requires
more coding.

pumping messages inside a message handler is something i''ve never tried in
..NET, so I don''t know if it is possible or not.

kind regards,
Bruno.
br**********************@hotmail.com
Remove only "_nos_pam"


定期调用CurrentThread->加入(0),这隐含地调用

CoWaitForMultipleHandles和返回。


Willy。

< ni ************* @ motorola.com>在消息中写道

新闻:11 ********************** @ o13g2000cwo.googlegr oups.com ...

|大家好,

|

|我在一个函数中做了很长时间的处理,我正在显示

|使用进度条进行治疗的进展。代码是

|像这样:

|

|每个(条目中的条目)//约100个条目

| {

| TreatmentForOneOr2Secs();

| this-> progressBar1-> PerformStep();

| }

|

|

|在调试过程中,调试器告诉我:

|

|托管调试助手''ContextSwitchDeadlock''已检测到

| 'd:\ test\NetSendDotNet \ debug> \\ NetSendDotNet.exe''中的问题。

|附加信息:CLR无法从COM过渡

|上下文0x189558到COM上下文0x189408持续60秒。线程

|拥有目的地上下文/公寓的人最有可能要做的是
|非抽空等待或处理非常长时间运行的操作没有

|抽取Windows消息。这种情况一般都是负面的b $ b |性能影响甚至可能导致应用程序变为非b $ b |响应或内存使用随着时间的推移不断累积。为了避免

|这个问题,所有单线程公寓(STA)线程都应该使用

|抽等待原语(如CoWaitForMultipleHandles)和

|在长时间运行期间经常抽取消息。

|

|

|特别是:

|为了避免这个问题,所有单线程公寓(STA)线程

|应该使用抽等等原语(如CoWaitForMultipleHandles)

|并且在长时间运行期间定期抽取信息。

|

|那么,我怎么能收到消息呢?或者,我应该使用一个线程(以及如何?)

|

|

|谢谢你的帮助

|

|

| Nicolas H.

|
Call routinely CurrentThread->Join(0), this implicitely calls
CoWaitForMultipleHandles and returns.

Willy.
<ni*************@motorola.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
| Hi all,
|
| i''m doing a quite long treatment in a function, and i''m showing the
| progress of the treatment with a progressbar. The code is something
| like this :
|
| for each(entry in entries) // about 100 entries
| {
| TreatmentForOneOr2Secs();
| this->progressBar1->PerformStep();
| }
|
|
| during the debug, the debugger tells me that :
|
| Managed Debugging Assistant ''ContextSwitchDeadlock'' has detected a
| problem in ''d:\test\NetSendDotNet\debug\NetSendDotNet.exe''.
| Additional Information: The CLR has been unable to transition from COM
| context 0x189558 to COM context 0x189408 for 60 seconds. The thread
| that owns the destination context/apartment is most likely either doing
| a non pumping wait or processing a very long running operation without
| pumping Windows messages. This situation generally has a negative
| performance impact and may even lead to the application becoming non
| responsive or memory usage accumulating continually over time. To avoid
| this problem, all single threaded apartment (STA) threads should use
| pumping wait primitives (such as CoWaitForMultipleHandles) and
| routinely pump messages during long running operations.
|
|
| Specially :
| To avoid this problem, all single threaded apartment (STA) threads
| should use pumping wait primitives (such as CoWaitForMultipleHandles)
| and routinely pump messages during long running operations.
|
| So, how can i pumping messages ? or, should i use a thread (and how ?)
|
|
| Thanks for your help
|
|
| Nicolas H.
|


>常规调用CurrentThread-> Join(0),这隐含地调用
>Call routinely CurrentThread->Join(0), this implicitely calls
CoWaitForMultipleHandles并返回。
Willy。
CoWaitForMultipleHandles and returns. Willy.




非常感谢willy,这是工作和消息。

但是在我的表格上,我有一个标签,进度条。

在此期间,进度条会刷新,但不会刷新标签。

我应该拨打一个明确的更新吗?


这是我的代码:

this-> Show();

this-> Update();

for每个(条目中的条目)

{

TreatmentForOneOr2Secs();

this-> progressBar1-> PerformStep();

System :: Threading :: Thread :: CurrentThread-> Join(0);

}

this-> Hide();


(这个是表格)


你知道为什么标签没有刷新吗?

提前致谢


Nicolas



Thanks willy, this is working and pumping message.
But on my form, i have a label and a progress bar.
During this time, the progress bar is refreshed, but not the label.
Should i call an explicit update ?

This is my code :
this->Show();
this->Update();
for each(entry in entries)
{
TreatmentForOneOr2Secs();
this->progressBar1->PerformStep();
System::Threading::Thread::CurrentThread->Join(0);
}
this->Hide();

("this" is the form)

Do you know why the label isn''t refreshed ?

Thanks in advance

Nicolas


这篇关于如何使用winforms实现消息泵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆