gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 08:05:07 24 4
gpt4 key购买 nike

所以,关注 this ,我决定在专用 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;
}

关于c# - 如何将消息发布到运行消息泵的 STA 线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21680738/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com