我知道我不能生成不同的线程并将其放入 UI 线程中以将其添加到 Visual Tree 中,因为它会抛出一个异常,它无法访问该对象,因为不同的线程拥有它。
我目前的情况是我正在大量创建 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 控件。说,运行,表格,段落等。因此,ListBox、TreeViews等不适用于此场景。