目前没有人详细讨论单独STA线程的情况(尽管概念完全相同)。
因此,让我们想象一下在按钮点击时添加了一个简单的选项卡控件。
private void button_Click(object sender, RoutedEventArgs e)
{
TabItem newTab = new TabItem() { Header = "New Tab" };
tabMain.Items.Add(newTab);
}
如果我们将它移动到另一个STA线程
private void button_Click(object sender, RoutedEventArgs e)
{
Thread newThread = new Thread(new ThreadStart(ThreadStartingPoint));
newThread.SetApartmentState(ApartmentState.STA);
newThread.IsBackground = true;
newThread.Start();
}
private void ThreadStartingPoint()
{
TabItem newTab = new TabItem() { Header = "New Tab" };
tabMain.Items.Add(newTab);
}
当然,我们会收到一个 System.InvalidOperationException
的异常。
现在,如果我们添加这个控件会发生什么呢?
private void AddToParent(string header)
{
TabItem newTab = new TabItem() { Header = header };
tabMain.Items.Add(newTab);
}
使用委托方法?
public void DelegateMethod(string header)
{
tabMain.Dispatcher.BeginInvoke(
new Action(() => {
this.AddToParent(header);
}), null);
}
如果您调用它,它就能工作。
private void button_Click(object sender, RoutedEventArgs e)
{
Thread newThread = new Thread(new ThreadStart(ThreadStartingPoint));
newThread.SetApartmentState(ApartmentState.STA);
newThread.IsBackground = true;
newThread.Start();
}
private void ThreadStartingPoint()
{
DelegateMethod("new tab");
}
因为现在我们将可视树保留在原始线程中。