我正在创建一种“加载屏幕”,它将在一些繁重的处理之前从类库中显示出来,然后它会在处理完成时隐藏。我的问题是,无论我做什么,繁重的处理似乎阻止了UI线程。我必须使用[STAThread]
属性设置方法,以便实际创建窗口。然后我使用以下方式显示窗口:
bw = new BusyWindow();
bw.Show();
然后在处理完成后用bw.Hide()
隐藏它。我已经为处理创建了一个Task,所以它应该在一个单独的线程上运行..?当然,除非STAThread完全混乱了吗?
更多代码:
var taskStart = Task.Factory.StartNew(() => ShowBusyWindow());
var taskProcess = taskStart.ContinueWith((antecedent) => GetInternal());
var taskEnd = taskProcess.ContinueWith((antecedent) => HideBusyWindow());
return taskProcess.Result;
和ShowBusywindow
public void ShowBusyWindow()
{
bw = new BusyWindow();
bw.Show();
}
和HideBusyWindow:
public void HideBusyWindow()
{
bw.Close();
}
我还应该提一下,我正在尝试将此库公开给COM,因此可以从某些VB6代码运行它。我不知道这对任何事情都有影响......?
答案 0 :(得分:6)
好的,所以可以使用以下方法从类库或任何其他线程调用WPF窗口:
thread = new Thread(() =>
{
bw = new BusyWindow();
bw.Show();
bw.Closed += (s, e) => bw.Dispatcher.InvokeShutdown();
Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
//thread.IsBackground = true;
thread.Start();
你真的不需要IsBackground。唯一需要的是在窗口关闭时线程Dispatcher没有关闭。如果它没有关闭,它会创建一个“鬼线”。
公寓状态显然必须设置为STA,因此Window实际上可以创建。根据{{3}}网站,单线程WPF窗口对于非常密集的UI窗口(大量图形等)非常有用。
要关闭窗口,我只需调用thread.Abort()
。我不认为这是最干净的方法,但它适用于我需要的东西。