Прежде чем вы ставите мой вопрос как дубликат, выслушайте меня.
У большинства людей есть длительная работа, отличная от UI, которую они выполняют, и нужно разблокировать поток пользовательского интерфейса. У меня длинная работа UI, которая должна запускаться в потоке пользовательского интерфейса, который блокирует остальную часть моего приложения. В принципе, я динамически строю DependencyObject во время выполнения и добавляю их к компоненту пользовательского интерфейса в своем приложении WPF. Количество DependencyObject, которое необходимо создать, зависит от пользовательского ввода, которого нет предела. Один из тестовых входов, которые у меня есть, составляет около 6000 DependencyObject, которые необходимо создать, и загрузка их занимает пару минут.
Обычное решение использования фонового работника в этом случае не работает, поскольку после того, как DependencyObject создаются фоновым рабочим, они больше не могут быть добавлены в компонент пользовательского интерфейса, поскольку они были созданы в фоновом потоке.
Моя текущая попытка решения - запустить цикл в фоновом потоке, отправить в поток пользовательского интерфейса для каждой единицы работы, а затем вызвать Thread.Yield(), чтобы дать потоку пользовательского интерфейса возможность обновиться. Это почти работает - поток пользовательского интерфейса получает возможность обновить себя пару раз во время операции, но приложение по-прежнему по-прежнему заблокировано.
Как я могу заставить приложение продолжать обновлять пользовательский интерфейс и обрабатывать события в других формах во время этой длительной операции?
EDIT: В соответствии с запросом, пример моего текущего "решения":
private void InitializeForm(List<NonDependencyObject> myCollection)
{
Action<NonDependencyObject> doWork = (nonDepObj) =>
{
var dependencyObject = CreateDependencyObject(nonDepObj);
UiComponent.Add(dependencyObject);
// Set up some binding on each dependencyObject and update progress bar
...
};
Action background = () =>
{
foreach (var nonDependencyObject in myCollection)
{
if (nonDependencyObject.NeedsToBeAdded())
{
Dispatcher.Invoke(doWork, nonDependencyObject);
Thread.Yield(); //Doesn't give UI enough time to update
}
}
};
background.BeginInvoke(background.EndInvoke, null);
}
Изменение Thread.Yield() до Thread.Sleep(1) похоже на работу, но действительно ли это хорошее решение?