如何将消息发布到运行消息泵的STA线程?

巴瓦扎

因此,在此之后,我决定在专用STA线程上显式实例化COM对象。实验表明,COM对象需要一个消息泵,该泵是通过调用Application.Run()以下命令创建的

private MyComObj _myComObj;

// Called from Main():
Thread myStaThread = new Thread(() =>
{
    _myComObj = new MyComObj();
    _myComObj.SomethingHappenedEvent += OnSomthingHappened;
    Application.Run();
});
myStaThread.SetApartmentState(ApartmentState.STA);
myStaThread.Start();

如何从其他线程发布STA线程的消息泵中的消息?

注意:为简洁起见,我对问题进行了大量编辑。@Servy的答案的某些部分现在似乎无关紧要,但它们是针对原始问题的。

汉斯·帕桑特

请记住,Windows为STA线程创建的消息队列已经是线程安全队列的实现。因此,仅将其用于您自己的目的。这是您可以使用的基类,派生自己的基类以包含COM对象。重写Initialize()方法,线程准备开始执行代码时将立即调用它。不要忘记在覆盖中调用base.Initialize()。

如果要在该线程上运行代码,然后使用BeginInvoke或Invoke方法,就像使用Control.Begin / Invoke或Dispatcher.Begin / Invoke方法一样。调用其Dispose()方法关闭线程,这是可选的。请注意,只有当您100%确定所有COM对象都已完成时,这样做才是安全的。由于您通常没有保证,因此最好不要。

using System;
using System.Threading;
using System.Windows.Forms;

class STAThread : IDisposable {
    public STAThread() {
        using (mre = new ManualResetEvent(false)) {
            thread = new Thread(() => {
                Application.Idle += Initialize;
                Application.Run();
            });
            thread.IsBackground = true;
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
            mre.WaitOne();
        }
    }
    public void BeginInvoke(Delegate dlg, params Object[] args) {
        if (ctx == null) throw new ObjectDisposedException("STAThread");
        ctx.Post((_) => dlg.DynamicInvoke(args), null);
    }
    public object Invoke(Delegate dlg, params Object[] args) {
        if (ctx == null) throw new ObjectDisposedException("STAThread");
        object result = null;
        ctx.Send((_) => result = dlg.DynamicInvoke(args), null);
        return result;
    }
    protected virtual void Initialize(object sender, EventArgs e) {
        ctx = SynchronizationContext.Current;
        mre.Set();
        Application.Idle -= Initialize;
    }
    public void Dispose() {
        if (ctx != null) {
            ctx.Send((_) => Application.ExitThread(), null);
            ctx = null;
        }
    }
    private Thread thread;
    private SynchronizationContext ctx;
    private ManualResetEvent mre;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何将消息发布到运行消息泵的STA线程?

来自分类Dev

StaTaskScheduler和STA线程消息泵送

来自分类Dev

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

来自分类Dev

如何保持线程的消息泵响应

来自分类Dev

如何将消息发布到受限端点AWS SNS

来自分类Dev

如何泵送COM消息?

来自分类Dev

Signalr我如何将消息从服务器发布到呼叫者

来自分类Dev

如何将消息从后台服务发布到UI片段?

来自分类Dev

PostMessage:如何将消息发布到没有窗口的进程?

来自分类Dev

是否从另一个线程调用SendMessage()将消息发布到消息队列?

来自分类Dev

如何在非WinForms程序集中泵送STA线程?

来自分类Dev

线程到主UI线程的发布消息被阻止/删除

来自分类Dev

将状态消息发布到Facebook?

来自分类Dev

使用Gatling将消息发布到ActiveMQ

来自分类Dev

将消息从 AWS SNS 发布到 SQS

来自分类Dev

同步将消息发布到worker_thread。发送线程被阻止,worker_thread被解除阻止

来自分类Dev

如何将“消息”从qmake传递到C ++?

来自分类Dev

如何将选定的日志消息复制到sysout?

来自分类Dev

如何将消息集成到Ubuntu Touch App中?

来自分类Dev

如何将错误消息重定向到/ dev / null?

来自分类Dev

如何将消息重定向到相应的 LUIS 应用

来自分类Dev

如何将 rsyslog 消息配置到特定端口?

来自分类Dev

如何将聊天消息存储到离子存储中?

来自分类Dev

RabbitMQ:将消息路由到线程

来自分类Dev

RabbitMQ:将消息路由到线程

来自分类Dev

模态对话框的消息泵如何与主应用程序消息泵交互?

来自分类Dev

如何从SQL Server发布消息到RabbitMQ?

来自分类Dev

挂钩到由DllSurrogate在DllHost中激活的STA Apartment COM对象的消息泵

来自分类Dev

挂钩到由DllSurrogate在DllHost中激活的STA Apartment COM对象的消息泵

Related 相关文章

  1. 1

    如何将消息发布到运行消息泵的STA线程?

  2. 2

    StaTaskScheduler和STA线程消息泵送

  3. 3

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

  4. 4

    如何保持线程的消息泵响应

  5. 5

    如何将消息发布到受限端点AWS SNS

  6. 6

    如何泵送COM消息?

  7. 7

    Signalr我如何将消息从服务器发布到呼叫者

  8. 8

    如何将消息从后台服务发布到UI片段?

  9. 9

    PostMessage:如何将消息发布到没有窗口的进程?

  10. 10

    是否从另一个线程调用SendMessage()将消息发布到消息队列?

  11. 11

    如何在非WinForms程序集中泵送STA线程?

  12. 12

    线程到主UI线程的发布消息被阻止/删除

  13. 13

    将状态消息发布到Facebook?

  14. 14

    使用Gatling将消息发布到ActiveMQ

  15. 15

    将消息从 AWS SNS 发布到 SQS

  16. 16

    同步将消息发布到worker_thread。发送线程被阻止,worker_thread被解除阻止

  17. 17

    如何将“消息”从qmake传递到C ++?

  18. 18

    如何将选定的日志消息复制到sysout?

  19. 19

    如何将消息集成到Ubuntu Touch App中?

  20. 20

    如何将错误消息重定向到/ dev / null?

  21. 21

    如何将消息重定向到相应的 LUIS 应用

  22. 22

    如何将 rsyslog 消息配置到特定端口?

  23. 23

    如何将聊天消息存储到离子存储中?

  24. 24

    RabbitMQ:将消息路由到线程

  25. 25

    RabbitMQ:将消息路由到线程

  26. 26

    模态对话框的消息泵如何与主应用程序消息泵交互?

  27. 27

    如何从SQL Server发布消息到RabbitMQ?

  28. 28

    挂钩到由DllSurrogate在DllHost中激活的STA Apartment COM对象的消息泵

  29. 29

    挂钩到由DllSurrogate在DllHost中激活的STA Apartment COM对象的消息泵

热门标签

归档