我可以通过以下代码在新线程中打开一个新窗口。
以下代码来自MainWindow.xaml.cs
private void buttonStartStop_Click(object sender, RoutedEventArgs e)
{
Test test = new Test();
Thread newWindowThread = new Thread(new ThreadStart(test.start));
newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.IsBackground = true;
newWindowThread.Start();
}
以及test.start()
中的以下内容public void start()
{
OutputWindow outputwindow = new OutputWindow();
outputwindow.Show();
Output.print("Begin");
System.Windows.Threading.Dispatcher.Run();
Output.print("FINAL");
System.Windows.Threading.Dispatcher.Run();
}
以下内容来自输出类
public static void print(String str)
{
Dispatcher uiDispatcher = OutputWindow.myOutputWindow.Dispatcher;
uiDispatcher.BeginInvoke(new Action(delegate() { OutputWindow.myOutputWindow.textBoxOutput.AppendText(str + "\n"); }));
uiDispatcher.BeginInvoke(new Action(delegate() { OutputWindow.myOutputWindow.textBoxOutput.ScrollToLine(OutputWindow.myOutputWindow.textBoxOutput.LineCount - 1); }));
}
public static void printOnSameLine(String str)
{
Dispatcher uiDispatcher = OutputWindow.myOutputWindow.Dispatcher;
uiDispatcher.BeginInvoke(new Action(delegate() { OutputWindow.myOutputWindow.textBoxOutput.AppendText(str); }));
uiDispatcher.BeginInvoke(new Action(delegate() { OutputWindow.myOutputWindow.textBoxOutput.ScrollToLine(OutputWindow.myOutputWindow.textBoxOutput.LineCount - 1); }));
}
“Begin”是否在文本框中打印但“FINAL”没有打印,我希望Test类中的start方法通过程序更新outputwindow中的文本框。这样做的最佳方式是什么?
提前谢谢
答案 0 :(得分:0)
我不确定你想做什么。由于您调用了System.Windows.Threading.Dispatcher.Run(),因此无法打印FINAL是正常的。此方法使线程保持活动状态并侦听事件。你可以看一下它,就像你在Run方法中有while(true){}一样。方法将继续运行,直到Dispatcher关闭。您应该保持后台线程处于活动状态,并在需要设置消息时从另一个线程调用静态方法。这是一个例子:
// reference to window in another thread
Window outputWindow = null;
Thread thread = new Thread(() =>
{
// another thread
outputWindow = new Window();
outputWindow.Show();
// run event loop
System.Windows.Threading.Dispatcher.Run();
}) { ApartmentState = ApartmentState.STA, IsBackground = true };
thread.Start();
while (outputWindow == null)
{
// wait until the window in another thread has been created
Thread.Sleep(100);
}
// simulate process
for (int i = 0; i < 10; i++)
{
outputWindow.Dispatcher.BeginInvoke((Action)(() => { outputWindow.Title = i.ToString(); }), System.Windows.Threading.DispatcherPriority.Normal);
Thread.Sleep(500); // simulate some hard work so we can see the change on another window's title
}
// close the window or shutdown dispatcher or abort the thread...
thread.Abort();
修改强>
这可能很快&amp;脏的通用解决方案DoSomeHardWork为等待窗口创建另一个GUI线程,显示进度信息。这个窗口创建了实际完成工作的工作线程。工作在方法Action中实现。第一个参数是等待窗口,因此您可以从工作线程更改它。当然,在现实世界中,你应该通过接口而不是直接进行窗口实现,但这只是一个例子。第二个参数是对象,因此您可以将所需的任何内容传递给工作线程。如果需要更多参数传递object []或修改方法签名。在这个例子中,我用计数器和睡眠来模拟努力工作。您可以多次单击按钮执行此代码,您将看到所有等待窗口计数自己的计数器而不冻结。这是代码:
public static void DoSomeHardWork(Action<Window, object> toDo, object actionParams)
{
Thread windowThread = new Thread(() =>
{
Window waitWindow = new Window();
waitWindow.Loaded += (s, e) =>
{
Thread workThread = new Thread(() =>
{
// Run work method in work thread passing the
// wait window as parameter
toDo(waitWindow, actionParams);
}) { IsBackground = true };
// Start the work thread.
workThread.Start();
};
waitWindow.Show();
Dispatcher.Run();
}) { ApartmentState = ApartmentState.STA, IsBackground = true };
// Start the wait window thread.
// When window loads, it will create work thread and start it.
windowThread.Start();
}
private void MyWork(Window waitWindow, object parameters)
{
for (int i = 0; i < 10; i++)
{
// Report progress to user through wait window.
waitWindow.Dispatcher.BeginInvoke((Action)(() => waitWindow.Title = string.Format("{0}: {1}", parameters, i)), DispatcherPriority.Normal);
// Simulate long work.
Thread.Sleep(500);
}
// The work is done. Shutdown the wait window dispather.
// This will stop listening for events and will eventualy terminate
// the wait window thread.
waitWindow.Dispatcher.InvokeShutdown();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
DoSomeHardWork(MyWork, DateTime.Now);
}
答案 1 :(得分:0)
理想情况下,创建UI元素的线程(UI线程)也拥有元素。使用调度程序,您所做的就是将非UI相关处理推送到后台线程。后台进程完成后,结果将再次推送回主UI线程。有关示例示例,请查看:http://weblogs.asp.net/pawanmishra/archive/2010/06/06/understanding-dispatcher-in-wpf.aspx