首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在后台线程中创建元素,然后添加到主界面

在后台线程中创建元素,然后添加到主界面
EN

Stack Overflow用户
提问于 2009-12-16 19:21:09
回答 5查看 3K关注 0票数 1

我在WPF中线程化有问题。我想创建一个复杂的用户界面,然后将其添加到我的主窗口中。在创建这个复杂的用户界面时,我想在我的主窗口中显示一个进度条。我想这只能用线来做。但是有一个问题。无法将创建的元素添加到主窗口,因为它是在单独的线程中创建的。有没有人知道有没有可能将后台线程中创建的UIElements转移到主线程。如果我用一种简单的方式来尝试,它会告诉我这个对象不能被访问,因为它在一个单独的线程中。我已经让我的进度条线程安全了。

我希望下面的例子能更好地解释我想要做的事情。

代码语言:javascript
复制
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添加到变量,然后再添加主线程也是不可能的。

代码语言:javascript
复制
//this is also impossible

//in background-thread
form = new Formular

//in main-thread
tcForm.Children.Add(form);

我希望有一种方法可以做到这一点。如果有什么建议就好了,

谢谢,马丁

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-12-16 19:27:33

你应该使用Dispatcher.Invoke方法

代码语言:javascript
复制
...
        this.Dispatcher.Invoke(delegate{ tcForm.Children.Add(new Formular());
           ProgressBar.AddProgress();};)
....

编辑

如果Fromular()对象工作时间较长,则可以在调度之前创建该对象

代码语言:javascript
复制
var f = new Formular();
this.Dispatcher.Invoke(delegate{ tcForm.Children.Add(f);
               ProgressBar.AddProgress();};)
票数 3
EN

Stack Overflow用户

发布于 2009-12-16 19:25:24

如果你想要做的就是更新一个进度条(或类似的),那么你应该在主线程中预先创建所有的UI,然后使用窗体的Invoke method将状态更新从后台线程发送到主线程(例如,发送一个int来表示进度介于0和100%之间)

我不认为有一种方法可以在线程之间共享windows窗体控件。

编辑: WPF好的,我现在看到这是标记为的。答案保持不变,但不是在控件上调用,而是使用Dispatcher类(每个图形元素都包含对正确的dispatcher的引用)。您还可以按照另一个答案中的建议使用BackgroundWorker类。

票数 1
EN

Stack Overflow用户

发布于 2009-12-16 19:27:18

我对WPF知之甚少,但我刚刚了解到BackGroundWorker,它可能会为你做这项工作。

http://dotnetperls.com/backgroundworker

您只需处理WorkerCompleted事件,该事件在任务之后引发,应该在主线程中运行。它还可以报告进度以更新您的进度条。

示例:

代码语言:javascript
复制
    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);
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1914037

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档