我知道不能在UI线程中生成不同的线程并将其放入Visual Tree,因为这会引发异常,即不能访问该对象,因为不同的线程拥有它。
我的当前情况是我正在大量地生成UI控件运行时,比如说200个 (FrameworkContentElement) 控件,并将其添加到 DockWindow 中。是否可能在创建这些控件的同时不冻结UI,尝试将它们加载到UI线程中?我甚至不能显示进度对话框,因为那将使用UI线程,同时在另一个线程上进行工作是可以的,如果我需要处理数据并将其放入UI中,但这次我需要创建这些UI控件。
我考虑的一种方法是创建UI控件并将它们序列化到MemoryStream中,然后将它们加载到UI线程中,这里的一个问题是我必须重新附加DataContext到控件上,但是那时我可以将其委托给另一个线程。问题仍然是这样做是否可行?
我尝试混合Task和Thread对象以使ApartmentState变为STA,但还是没有成功。
我的当前情况是我正在大量地生成UI控件运行时,比如说200个 (FrameworkContentElement) 控件,并将其添加到 DockWindow 中。是否可能在创建这些控件的同时不冻结UI,尝试将它们加载到UI线程中?我甚至不能显示进度对话框,因为那将使用UI线程,同时在另一个线程上进行工作是可以的,如果我需要处理数据并将其放入UI中,但这次我需要创建这些UI控件。
我考虑的一种方法是创建UI控件并将它们序列化到MemoryStream中,然后将它们加载到UI线程中,这里的一个问题是我必须重新附加DataContext到控件上,但是那时我可以将其委托给另一个线程。问题仍然是这样做是否可行?
我尝试混合Task和Thread对象以使ApartmentState变为STA,但还是没有成功。
public static Task<T> StartSTATask<T>(Func<T> func)
{
var tcs = new TaskCompletionSource<T>();
Thread thread = new Thread(() =>
{
try
{
tcs.SetResult(func());
}
catch (Exception e)
{
tcs.SetException(e);
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return tcs.Task;
}
编辑:这些控件再次是FrameworkContentElement,虚拟化控件在这种情况下不起作用。 这是使用FlowDocument控件在运行时创建控件。 比如Runs,Tables,Paragraphs等。 因此,在这种情况下ListBox,TreeViews等不适用。