什么是消息泵? [英] What is a message pump?

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

问题描述

在<一个href=\"http://social.msdn.microsoft.com/Forums/en/asmxandxml/thread/1cdc8931-e215-4ae7-9171-768c2600b316\">this螺纹(贴在大约一年前)存在的,可以配备在非交互式会话运行Word的问题进行了讨论。鉴于那里的(相当强)的建议是不要这么做。在一个帖子中指出办公室的API都假设您在桌面上的交互式会话运行Office,带有显示器,键盘和鼠标,而最重要的是,消息泵。我不知道那是什么。 (我在C#编程了只有大约一年。我的其他编程经验一直主要使用ColdFusion)

In this thread (posted about a year ago) there is a discussion of problems that can come with running Word in a non-interactive session. The (quite strong) advice given there is not to do so. In one post it is stated "The Office APIs all assume you are running Office in an interactive session on a desktop, with a monitor, keyboard and mouse and, most importantly, a message pump." I'm not sure what that is. (I've been programming in C# for only about a year; my other programming experience has primarily been with ColdFusion.)

我的方案,通过大量的RTF文件运行,以提取两部分信息用于构建医疗报告数。而不是试着找出在工作RTF格式说明怎么样,我决定只在Word中打开它们,拉文从那里出来(没有实际启动GUI)。偶尔,程序处理一个文件的中间打嗝,并留下了一个字线打开附加到文件(我仍然要弄清楚如何关闭了一个向下)。当我重新运行该程序,当然我得到的通知,有使用该文件一个线程,并没有我想开一个只读副本?当我说是的,字GUI突然从无处弹出,开始处理这些文件。我不知道为什么会发生;但是看起来,也许曾经的对话框弹出消息泵开始主推的界面到Windows呢?

My program runs through a large number of RTF files to extract two pieces of information used to construct a medical report number. Rather than try and figure out how the formatting instructions in RTF work, I decided to just open them in Word and pull the text out from there (without actually starting the GUI). Occasionally, the program hiccuped in the middle of processing one file, and left a Word thread open attached to that document (I still have to figure out how to shut that one down). When I re-ran the program, of course I got a notification that there was a thread using that file, and did I want to open a read-only copy? When I said Yes, the Word GUI suddenly popped up from nowhere and started processing the files. I was wondering why that happened; but it looks like maybe once the dialog box popped up the message pump started pushing the main GUI to Windows as well?

而现在我冥思苦想了别的东西。昨天我提出这个问题作为未注册的用户 - 然后清除我的cookies,使其无法弄清楚我是谁;现在,作为一个注册用户,我要从头开始: - /他们为什么不更容易基于cookie的登记基于OpenID的连接? HMF。

And now I'm puzzling about something else. Yesterday I posed this question as an unregistered user - and then cleared my cookies so that it couldn't figure out who I was; now as a registered user I have to start over from scratch :-/ Why don't they make it easier to connect cookie-based registration with OpenID-based? Hmf.

推荐答案

一个消息循环是一小块code存在于任何原生的Windows程序。它大致是这样的:

A message loop is a small piece of code that exists in any native Windows program. It roughly looks like this:

MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{ 
   TranslateMessage(&msg); 
   DispatchMessage(&msg); 
} 

该GetMessage函数()的Win32 API检索从Windows的消息。你的程序通常花费它的时间有99.99%,等待Windows来告诉它一些有趣的事情发生了。的TranslateMessage()是一个辅助函数转换键盘消息。在DispatchMessage()确保窗口过程调用消息。

The GetMessage() Win32 API retrieves a message from Windows. Your program typically spends 99.99% of its time there, waiting for Windows to tell it something interesting happened. TranslateMessage() is a helper function that translates keyboard messages. DispatchMessage() ensures that the window procedure is called with the message.

每个GUI支持.NET程序有一个消息循环,它是由Application.Run启动()。

Every GUI enabled .NET program has a message loop, it is started by Application.Run().

消息循环到Office的相关性是关系到COM。 Office程序启用COM程序,这就是Microsoft.Office.Interop类的工作。 COM需要代表一个COM组件类的保健线程,它可以确保一个COM接口上进行调用总是从正确的线。大多数COM类在声明自己的ThreadingModel,目前最常见的(包括Office)使用公寓注册表中的注册表项。这意味着,唯一安全的方法来调用接口的方法是通过从创建类对象在同一个线程调用。或者换一种说法:目前大多数COM类不是线程安全的。

The relevance of a message loop to Office is related to COM. Office programs are COM-enabled programs, that's how the Microsoft.Office.Interop classes work. COM takes care of threading on behalf of a COM coclass, it ensures that calls made on a COM interface are always made from the correct thread. Most COM classes have a registry key in the registry that declares their ThreadingModel, by far the most common ones (including Office) use "Apartment". Which means that the only safe way to call an interface method is by making the call from the same thread that created the class object. Or to put it another way: by far most COM classes are not thread-safe.

每个COM使线程属于一个COM公寓。有两种,单线程公寓(STA)和多线程公寓(MTA)。公寓线程COM类必须在STA线程创建。你可以看到这个早在.NET程序,Windows窗体的UI线程的入口点或WPF程序有[STAThread]属性。其他线程公寓模型由Thread.SetApartmentState()方法来设置。

Every COM enabled thread belongs to a COM apartment. There are two kinds, Single Threaded Apartments (STA) and a Multi Thread Apartment (MTA). An apartment threaded COM class must be created on an STA thread. You can see this back in .NET programs, the entry point of the UI thread of a Windows Forms or WPF program has the [STAThread] attribute. The apartment model for other threads is set by the Thread.SetApartmentState() method.

如果UI线程不是STA的Windows管道的大部分地区将无法正常工作。值得注意的是拖动+下降,剪贴板,Windows对话框像打开文件对话框。和任何ActiveX控件和大多数COM服务器,如办公室。

Large parts of Windows plumbing won't work correctly if the UI thread is not STA. Notably Drag+Drop, the clipboard, Windows dialogs like OpenFileDialog. And any ActiveX control and most COM servers, like Office.

有关STA线程的硬性要求是,它应该不会阻塞,必须泵消息循环。消息循环是很重要的,因为这是COM使用编组的接口方法调用从一个线程到另一个。虽然.NET使易编组电话(Control.BeginInvoke或Dispatcher.BeginInvoke为例),它实际上是一个非常棘手的事情。执行该调用的线程必须是一个众所周知的状态。你不能只是随意中断线程,并迫使它作出一个方法调用,这会导致可怕的重入问题。线程应该是空闲,而不是忙于执行任何code是变异的程序的状态。

A hard requirement for an STA thread is that it should never block and must pump a message loop. The message loop is important because that's what COM uses to marshal an interface method call from one thread to another. Although .NET makes marshaling calls easy (Control.BeginInvoke or Dispatcher.BeginInvoke for example), it is actually a very tricky thing to do. The thread that executes the call must be in a well-known state. You can't just arbitrarily interrupt a thread and force it to make a method call, that would cause horrible re-entrancy problems. A thread should be "idle", not busy executing any code that is mutating the state of the program.

也许你能看到导致:是的,当一个程序正在执行的消息循环,它是空闲的。实际的编组发生通过COM创建一个隐藏的窗口,它使用PostMessage的有该窗口的窗口过程中执行code。在STA线程。消息循环确保了此code运行。

Perhaps you can see where that leads: yes, when a program is executing the message loop, it is idle. The actual marshaling takes place through a hidden window that COM creates, it uses PostMessage to have the window procedure of that window execute code. On the STA thread. The message loop ensures that this code runs.

这篇关于什么是消息泵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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