请记住,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;}


