是否可以在另一个线程中加载UserControl?

时间:2016-03-04 03:40:41

标签: c# wpf multithreading xaml user-controls

我是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中使用?我很困惑。

1 个答案:

答案 0 :(得分:1)

根据this answer

  

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

     

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

     

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

     

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

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