如果主线程是 STA 并创建一个 Window,则向其添加一些 UI 元素。然后产生另一个 STA 线程,第二个线程同样创建一些 UI 元素,它们是否在同一个“空间” [snip...]中进行,并且可以访问彼此的 UI 元素而不会造成死亡和破坏?
如果线程 A 和 B 都是 STA,那么它们可以各自创建和更新自己的UI 元素,但不能互相创建和更新。任何其他想要影响 UI 的线程都必须使用一种BeginInvoke
样式方法来请求相应的线程进行更新。
如果没有必要,那么我只会将该工作线程设为 STA 线程并继续进行,这样公平吗?还是我在招惹灾难?
如果工作线程已设置为 MTA 并已初始化,则您可能无法使工作线程成为 STA 线程。您可能需要创建一个新线程。
你怎么做呢?似乎您想System.Windows.*
为您的 UI 使用 WPF ( ) - 所以如果您“插入”的应用程序也在使用 WPF,您应该能够访问它并重新使用它的 UI 线程。如果没有,您可以创建一个新线程,并Application
在其上创建一个新线程并调用Run
. 这应该为您设置一个调度程序。
像这样的东西(从我在其他地方的一些工作代码中复制的伪代码排序)
Dispatcher dispatcher = null; // we 'get to' the UI thread via the dispatcher
if(Application.Current) { // re use an existing application's UI thread
dispatcher = Application.Current.Dispatcher;
} else {
var threadReadyEvent = new ManualResetEvent(false);
var uiThread = new Thread(() => {
Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
var application = new Application();
application.Startup += (sender, args) => {
dispatcher = application.Dispatcher;
threadReadyEvent.Set();
};
// apps have to have a "main window" - but we don't want one, so make a stub
var stubWindow = new Window {
Width = 1, Height = 1,
ShowInTaskbar = false, AllowsTransparency = true,
Background = Brushes.Transparent, WindowStyle = WindowStyle.None
};
application.Run(stubWindow);
}){ IsBackground = true };
uiThread.Start();
threadReadyEvent.WaitOne();
threadReadyEvent.Dispose();
}
dispatcher.Invoke(() => {
// ask the UI thread to do something and block until it finishes
});
dispatcher.BeginInvoke(() => {
// ask the UI thread to do something asynchronously
});
等等