我在WPF中线程化有问题。我想创建一个复杂的用户界面,然后将其添加到我的主窗口中。在创建这个复杂的用户界面时,我想在我的主窗口中显示一个进度条。我想这只能用线来做。但是有一个问题。无法将创建的元素添加到主窗口,因为它是在单独的线程中创建的。有没有人知道有没有可能将后台线程中创建的UIElements转移到主线程。如果我用一种简单的方式来尝试,它会告诉我这个对象不能被访问,因为它在一个单独的线程中。我已经让我的进度条线程安全了。
我希望下面的例子能更好地解释我想要做的事情。
StackPanel tcForm = new StackPanel();
Semaphore loadedSema = new Semaphore(0,1);
Thread thread = new Thread(new ThreadStart(delegate(){
//Formular should be created in background
tcForm.Children.Add(new Formular());
ProgressBar.AddProgress();
//...other things
loadedSema.Release();
}));
thread.start();
loadedSema.WaitOne();new Formular()运行的时间很长,所以我想在后台创建。
将Formular添加到变量,然后再添加主线程也是不可能的。
//this is also impossible
//in background-thread
form = new Formular
//in main-thread
tcForm.Children.Add(form);我希望有一种方法可以做到这一点。如果有什么建议就好了,
谢谢,马丁
发布于 2009-12-16 19:27:33
你应该使用Dispatcher.Invoke方法
...
this.Dispatcher.Invoke(delegate{ tcForm.Children.Add(new Formular());
ProgressBar.AddProgress();};)
....编辑
如果Fromular()对象工作时间较长,则可以在调度之前创建该对象
var f = new Formular();
this.Dispatcher.Invoke(delegate{ tcForm.Children.Add(f);
ProgressBar.AddProgress();};)发布于 2009-12-16 19:25:24
如果你想要做的就是更新一个进度条(或类似的),那么你应该在主线程中预先创建所有的UI,然后使用窗体的Invoke method将状态更新从后台线程发送到主线程(例如,发送一个int来表示进度介于0和100%之间)
我不认为有一种方法可以在线程之间共享windows窗体控件。
编辑: WPF好的,我现在看到这是标记为的。答案保持不变,但不是在控件上调用,而是使用Dispatcher类(每个图形元素都包含对正确的dispatcher的引用)。您还可以按照另一个答案中的建议使用BackgroundWorker类。
发布于 2009-12-16 19:27:18
我对WPF知之甚少,但我刚刚了解到BackGroundWorker,它可能会为你做这项工作。
http://dotnetperls.com/backgroundworker
您只需处理WorkerCompleted事件,该事件在任务之后引发,应该在主线程中运行。它还可以报告进度以更新您的进度条。
示例:
void worker_Start()
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork +=
new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync("MyArg");
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = new Formular();
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Controls.Add((Control)e.Result);
}https://stackoverflow.com/questions/1914037
复制相似问题