标签: message-pump

什么是消息泵?

这个帖子(大约一年前发布)中,讨论了在非交互式会话中运行Word时可能遇到的问题.那里给出的(非常强烈的)建议不会这样做.在一篇文章中,它表示"Office API都假设您在桌面上的交互式会话中运行Office,具有监视器,键盘和鼠标,最重要的是消息泵." 我不确定那是什么.(我用C#编程只用了一年左右;我的其他编程经验主要是使用ColdFusion.)

更新:

我的程序运行大量RTF文件,以提取用于构建医疗报告编号的两条信息.我没有尝试弄清楚RTF中的格式化指令是如何工作的,而是决定只在Word中打开它们并从那里拉出文本(而不是实际启动GUI).有时,程序在处理一个文件的中间打嗝,并留下了一个字线打开该文件附有(我仍然要弄清楚如何关闭一个向下).当我重新运行程序时,我当然得到一个通知,说有一个线程正在使用该文件,我是否想要打开一个只读副本?当我说"是"时,Word GUI突然突然冒出来并开始处理文件.我想知道为什么会这样; 但看起来可能一旦弹出对话框,消息泵开始将主GUI推送到Windows?

c# winapi message-pump winmain

95
推荐指数
5
解决办法
4万
查看次数

.NET Windows服务中的消息泵

我有一个用C#编写的Windows服务,它处理自助服务终端应用程序的所有外部硬件I/O. 我们的新设备之一是USB设备,它在本机DLL中附带API.我创建了一个正确的P/Invoke包装类.但是,必须使用HWnd将此API初始化为Windows应用程序,因为它使用消息泵来引发异步事件.

除了向硬件制造商请求我们提供不依赖于Windows消息泵的API之外,有没有办法在我的Windows服务中的新线程中手动实例化消息泵,我可以将其传递给此API ?我是否真的必须创建一个完整的Application类,或者是否有一个封装消息泵的低级.NET类?

.net c# service message-pump

25
推荐指数
1
解决办法
2万
查看次数

长时间运行时泵送Windows消息?

我正在运行的大型操作上收到以下消息:

CLR无法从COM上下文0x1fe458过渡到COM上下文0x1fe5c8 60秒.拥有目标上下文/公寓的线程很可能是在非抽空等待或处理非常长时间运行的操作而不抽取Windows消息.这种情况通常会对性能产生负面影响,甚至可能导致应用程序变得无响应或内存使用量随时间不断累积.为了避免这个问题,所有单线程单元(STA)线程都应该使用抽取等待原语(例如CoWaitForMultipleHandles)并在长时间运行操作期间定期泵送消息.

如何发送Windows消息,以便在长时间操作中不再出现此错误?

c# message-pump

22
推荐指数
2
解决办法
3万
查看次数

Windows默默捕获的异常,如何手动处理?

当消息泵中抛出异常时,我们遇到的问题是Windows静默地吃异常并允许应用程序继续运行.例如,我们创建了一个测试MFC MDI应用程序,并覆盖了OnDraw:

void CTestView::OnDraw(CDC* /*pDC*/)
{
    *(int*)0 = 0; // Crash

    CTestDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: add draw code for native data here
}
Run Code Online (Sandbox Code Playgroud)

在运行应用程序时,您会发现一个令人讨厌的错误消息,但实际上您什么也得不到.该程序似乎运行得很好,但是如果你检查输出窗口,你会看到:

Test.exe中0x13929384处的第一次机会异常:0xC0000005:访问冲突写入位置0x00000000.
Test.exe中0x77c6ee42的第一次机会异常:0xC0150010:当前执行的线程未激活的激活上下文无效.

我知道为什么我收到应用程序上下文异常,但为什么要静默处理?这意味着我们的应用程序在使用时可能会遇到严重问题,但我们永远不会知道它,因为我们的用户永远不会报告任何问题.

c++ windows mfc exception message-pump

20
推荐指数
3
解决办法
2万
查看次数

哪些阻塞操作导致STA线程泵送COM消息?

当一个COM对象在STA线程上实例化时,该线程通常必须实现一个消息泵,以便为来回调用其他线程(见这里).

可以手动泵送消息,或者依赖于某些(但不是全部)线程阻塞操作在等待时自动泵送COM相关消息的事实.文档通常无助于决定哪个是哪个(参见相关问题).

如何确定线程阻塞操作是否会在STA上泵送COM消息?

到目前为止的部分清单:

阻断其业务泵*:

阻止泵送的操作:

*注意Noseratio的答案说,即使是操作泵,也是为非常有限的未公开的COM特定消息集.

c# com interop message-pump

17
推荐指数
1
解决办法
3534
查看次数

如何使程序不显示在Alt-Tab或任务栏上

我有一个需要坐在后台的程序,当用户连接到RDP会话时,它会进行一些环境设置,然后启动一个程序.当程序关闭时,它将执行一些内务处理并注销会话.

我目前的做法是让终端服务器启动这个应用程序.这是作为Windows窗体应用程序构建的,以防止控制台窗口出现:

public static void Main()
{
    //(Snip...) Do some setup work

    Process proc = new Process();
    //(Snip...) Setup the process
    proc.Start();
    proc.WaitForExit();

    //(Snip...) Do some housecleaning

    NativeMethods.ExitWindowsEx(0, 0);
}
Run Code Online (Sandbox Code Playgroud)

我真的很喜欢这个,因为任务栏中没有任何项目,并且alt-tab中没有任何内容显示.但是为了做到这一点,我放弃了对void WndProc(ref Message m) So等函数的访问权限.现在我无法收听Windows消息(喜欢WTS_REMOTE_DISCONNECT或者WTS_SESSION_LOGOFF)并且没有使用的句柄,因为bool WTSRegisterSessionNotification(IntPtr hWnd, int dwFlags);我希望我的代码更强大,所以它会做清理工作如果用户在关闭程序之前注销或断开会话.

关于我如何吃蛋糕和吃它的任何建议?

c# handle message-pump

11
推荐指数
3
解决办法
6703
查看次数

清除Windows消息泵中的消息

我对Windows Message Pump了解不多,但我想使用Message Pump触发事件.

1)当我的Web浏览器控件导航到某些网站时,它会创建不同的文档完成事件.一旦我在WebBrowser_Document_Completed()中拥有了我需要的东西,我想忽略所有进一步的文档完成.

我该怎么做?

2)如果我在Document_Completed(...)中显示MessageBox(),它会显示多个消息框,因此它在并行线程上运行,但是当我调试它时,我发现它总是在主线程上运行.

什么时候创建了另外两个线程?

3)此外,当我按下关闭它关闭窗口但该过程仍然在后台运行.我没有使用任何其他线程但我在调试时仍然看到另外两个线程.

c# multithreading webbrowser-control message-pump

9
推荐指数
1
解决办法
831
查看次数

运行多个UI线程

跳到底部查看问题; 这只是一些额外的信息

我使用组件(GeckoFX)来渲染一些网站,很好,但它只能用于Windows窗体; 因为它必须绑定到可以绘制的WinForms对象.因为所有WinForms都在同一个线程中运行,所以我一次只能使用一个GeckoFX实例; 所以我决定以WinForm的形式创建一个"工人类",并在那里添加所有逻辑.表单不需要与主表单通信.

现在我可以启动10个窗口,它们最终会工作,但是每个新窗体都会在所有其他窗体处理完所有GeckoFX事件之前等待,因为你不能在一个线程上使用多个实例.此外,浏览器必须在UIThread上.所以:

是否可以创建多个UI线程(每个表单一个)?

我见过有人这样做([编辑:删除'坏'链接]),但没有人得到他的代码样本工作.让它工作的人最初使用某种形式的自定义消息来做这种事情,但我不知道如何实现这样的事情.

c# multithreading message-pump geckofx winforms

8
推荐指数
1
解决办法
1万
查看次数

控制台应用程序中的消息泵

我有一个用.NET编写的相当简单的控制台应用程序.有时应用程序在没有操作员的情况下以批处理模式运行,有时它是"自掏腰包"运行的.如果它以批处理模式运行,则会有一个定义的默认选项,允许程序自动运行.如果存在操作员,则还有其他选项允许用户从功能列表中进行选择.

由于我不想进入的原因,命令行参数不是首选.相反,我创建了一个10秒的窗口,操作员可以在其中选择一个功能.目前,我正在使用一个简单的while循环并从"in"流中读取输入.我在最后添加了一个Thread.Sleep调用,以防止while循环完全消耗处理器,但我想知道是否有更好的方法.

在Windows应用程序(Windows窗体WPF)中,有一个消息泵,它能够读取消息队列,然后将控制权返回给系统.即使像Visual Studio,SAS Enterprise GuideSQL Server Management Studio这样的重型应用程序在空闲时也几乎使用了0%的处理器.我的控制台应用程序可以获得相同的效果吗?

Thread.Sleep正在工作,但正如我所说,我想知道是否有更好的方法.

这是源代码:

class Program {
    static void Main( string[] args ) {

        DateTime l_startTime = DateTime.Now;

        Console.CursorVisible = false;
        Console.WriteLine( "Please select an option within 10 seconds..." );
        Console.WriteLine( "" );
        Console.WriteLine( " [1] Option A (DEFAULT)" );
        Console.WriteLine( " [2] Option 2" );
        Console.WriteLine( " [3] Option III" );

        int l_elapsedSeconds = 0;

        bool l_exit = false;
        while ( !l_exit …
Run Code Online (Sandbox Code Playgroud)

.net c# console-application message-pump

7
推荐指数
1
解决办法
6652
查看次数

如何在不窃取焦点和没有P/Invoke的情况下将消息(例如鼠标滚轮)转发到另一个控件?

当我用鼠标控制此控件时,我想转发一条消息(例如WM_MOUSEWHEEL),而不会窃取焦点.使用IMessageFilter(要添加到应用程序消息泵)并使用P/Invoke(d)SendMessage()转发消息,可以轻松解决此问题.问题是:我可以不使用P/Invoke做同样的事情(我在StackOverflow中找到的解决方案使用P/Invoke)吗?如果没有,为什么?

下面的代码是我用P/Invoke的解决方案.我只是用它new MessageForwarder(control, 0x20A).

/// <summary>
/// This class implements a filter for the Windows.Forms message pump allowing a
/// specific message to be forwarded to the Control specified in the constructor.
/// Adding and removing of the filter is done automatically.
/// </summary>
public class MessageForwarder : IMessageFilter
{
#region Fields

private Control _Control;
private Control _PreviousParent;
private HashSet<int> _Messages;
private bool _IsMouseOverControl;

#endregion // Fields

#region Constructors

public MessageForwarder(Control control, int message)
    : this(control, new int[] …
Run Code Online (Sandbox Code Playgroud)

c# focus message-pump mousewheel imessagefilter

6
推荐指数
1
解决办法
7926
查看次数