【问题标题】:Is it possible to load UserControl in another thread?是否可以在另一个线程中加载 UserControl?
【发布时间】:2016-03-04 03:40:40
【问题描述】:

我是 wpf 和多线程的新手。我有五个 UserControl,A-B-C-D-E 并返回 A

我正在尝试在加载 B 时重新加载 userControl A。

public class Main{
    public List<Page> pages;
    public UserControl currentScreen;
}

public class Page
{
    public UserControl userControl;
    public String xamlUrl;
    public void Invalidate()
    {
        try{
            var th = new Thread(() =>
            {
                ParseUserControl(xamlUrl);
            });
            th.SetApartmentState(ApartmentState.STA);
            th.Start();
        }
    }

    void ParseUserControl(String xamlUrl)
    {
        Console.WriteLine("ParseUserControl" + Thread.CurrentThread.ManagedThreadId);
        string strXaml = System.IO.File.ReadAllText(xamlUrl);
        UserControl uc = (UserControl)System.Windows.Markup.XamlReader.Parse(strXaml);
        UserControlParsedEventArgs args = new UserControlParsedEventArgs(uc);
        Application.Current.Dispatcher.Invoke(() => UserControlParsed(args));
    }


    void UserControlParsed(UserControlParsedEventArgs e)
    {
        Console.WriteLine("UserControlParsed " + Thread.CurrentThread.ManagedThreadId);
        userControl= e.userControl;
        Main.getInstance().currentScreen = userControl; //this line here throws error

    }
}

主要思想是让一个线程解析用户控件,并在加载用户控件后,将其发送回主屏幕进行显示。

但是,我收到此错误:“调用线程无法访问此对象,因为不同的线程拥有它。”

我认为这是因为 UserControl 是在不同的线程中创建的,但我已经做了 UserControl uc = e.userControl。

我已经检查了线程 ID:

main is running on id 8 <----------------------
ParseUserControl is running on id 9           |---always same
UserControlParsed is running on id 8 <---------

所以 UserControlParsed 中的 UserControl 属于线程 8,据说可以在 main 中使用?我很困惑。

【问题讨论】:

  • 通常,其他线程不会创建 UI 元素,而只是准备好数据。但即便如此,如果数据没有正确编组,数据也不能简单地绑定到 Gui 线程,这意味着数据必须与主窗口位于同一线程上。有很多不同的方法可以确保数据在主窗口线程上,您可以在谷歌搜索。
  • 如果您使用正确的数据绑定(无论如何您都应该这样做,而不是在代码隐藏中创建 ui 元素),那么您可以在您喜欢的任何线程中创建视图模型,并且 ui 会自行更新自动。

标签: c# wpf multithreading xaml user-controls


【解决方案1】:

根据this answer

在一个 (UI) 线程中创建的元素不能放入另一个在不同 UI 线程上创建的元素的逻辑/视觉树中。

混合在不同 UI 线程上创建的元素的解决方法:

有一种有限的解决方法,它可以为您提供一些能力,可以将在一个 UI 线程中创建的元素的呈现与在不同线程中创建的可视化树组合在一起......通过使用 HostVisual。看这个例子:

http://blogs.msdn.com/b/dwayneneed/archive/2007/04/26/multithreaded-ui-hostvisual.aspx

但这有点复杂。您应该将参数从后台线程传递到 UI 线程,并在 UI 线程中创建 UserControl。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多