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