Я настоятельно рекомендую отделить код пользовательского интерфейса от фонового кода и сделать так, чтобы уровень пользовательского интерфейса «управлял» бизнес / фоновым кодом.
В настоящее время OnClickPublish
вызывает PublishSlides
в фоновом потоке (Task.Run
), а затем PublishSlides
немедленно возвращается к потоку пользовательского интерфейса (Dispatcher.Invoke
) и запускает все тело метода в потоке пользовательского интерфейса. Это ничего не дает - просто перепрыгивая через потоки.
Чтобы правильно отделить пользовательский интерфейс от фонового кода потока, есть два основных метода и один менее распространенный метод.
Первый основной Техника заключается в использовании возвращаемых значений. Вместо того чтобы метод извлекал / вычислял данные, а затем обновлял пользовательский интерфейс с результатами результатов, просто попросите его извлечь / вычислить данные и вернуть . Затем вызывающий поток может решить, должен ли поиск / расчет выполняться в фоновом потоке (Task.Run
), а затем поместить данные в пользовательский интерфейс.
Второй основной метод заключается в использовании обновлений прогресса. Вместо того, чтобы «рабочий» метод доходил до пользовательского интерфейса и обновлял ход выполнения напрямую, он должен использовать IProgress<T>
для отчета о ходе выполнения. Затем вызывающий метод может решить, должна ли «работа» выполняться в фоновом потоке (Task.Run
), и он может передать реализацию выполнения (например, Progress<T>
), которая выполняет обновления прогресса в потоке пользовательского интерфейса.
Менее распространенным методом является активное обновление пользовательского интерфейса из непрерывно выполняемой фоновой операции. Я рекомендую использовать для этого SynchronizationContext
, но поскольку код более сложный и не относится к этому вопросу, я просто остановлюсь на этом.
Вот один пример того, как ваш код может выглядеть при использовании возвращаемых значений и await
. Точные данные будут зависеть от деталей вашего кода:
public async void OnClickPublish()
{
Loader loader = new Loader();
loader.Show();
PublishSlides(loader);
}
private async Task PublishSlides(Loader loader)
{
loader.LoaderMessage("Opration 1 start..");
List<SlideProperties> DBList = await Task.Run(() => objSlideImg.DBOpration());
try
{
await SendToCloudAsync(DBList);
loader.ShowSuccess("broadcasting..");
}
catch (Exception ex)
{
loader.LoaderMessage(ex.Message + " problem occur in cloud publish");
}
DashboardUI dashboard = new DashboardUI();
dashboard.ShowDashboard();
}
public async Task<bool> SendToCloudAsync(List<SlideProperties> DBList)
{
...
}