Сообщение Re: wpf, выполнение действий в разных потоках от 23.07.2016 22:02
Изменено 23.07.2016 22:30 VladCore
Здравствуйте, alex1010, Вы писали:
A>Есть, скажем, видеопанель, на которую выведены изображения от 5 ip-камер. Интерфейс построен на wpf.
A>При создании экземпляров камер/подключении к ним, возможны задержки до 15-20 секунд.
A>В результате, если тупо все делать в одно потоке, вся панель подвисает на это время, пока не пройдет инициализация камеры.
A>Логичное решение — вынести создание каждой камеры в отдельный поток.
A>Вопрос — на каком уровне это можно сделать?
На любом Делается так же как ина самом первом WPF:
Надеюсь ненадо отдельно указывать про то что вместо this.Run() можно писать любой_UI_элемент.Run()
Если надо результаты успешной инициализации передать в UI поток, пользуйтесь замыканиями. Надо показать как?
A>Я могу часть элементов визуальных, относящихся к wpf, вынести в отдельный поток?
не нужно.
A>Есть, скажем, видеопанель, на которую выведены изображения от 5 ip-камер. Интерфейс построен на wpf.
A>При создании экземпляров камер/подключении к ним, возможны задержки до 15-20 секунд.
A>В результате, если тупо все делать в одно потоке, вся панель подвисает на это время, пока не пройдет инициализация камеры.
A>Логичное решение — вынести создание каждой камеры в отдельный поток.
A>Вопрос — на каком уровне это можно сделать?
На любом Делается так же как ина самом первом WPF:
using System;
using System.Windows;
namespace WpfAsyncSample
{
using System.Threading;
using System.Windows.Threading;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Async(Action: () =>
{
// Долго инициализируемся и падаем
Thread.Sleep(2000);
this.RunSyncronously(() => label.Content = "Stage 1 done");
Thread.Sleep(3000);
this.RunSyncronously(() => label.Content = "Stage 2 done");
Thread.Sleep(4000);
throw new Exception();
},
Then: optionalException =>
{
// Мы в UI потоке
if (optionalException == null)
{
// Всё ok.
}
else
{
// Инициализация упала.
}
});
}
}
public static class DispatcableExtentions
{
public static void Async(this DispatcherObject ui, Action Action = null, Action<Exception> Then = null)
{
if (Action == null)
throw new ArgumentNullException("AsyncAction");
ThreadPool.QueueUserWorkItem(state =>
{
Exception ex;
try
{
Action();
ex = null;
}
catch (Exception ex2)
{
ex = ex2;
}
if (Then != null)
ui.Dispatcher.BeginInvoke(new Action(() => { Then(ex); }));
});
}
public static void RunSyncronously(this DispatcherObject ui, Action SyncAction)
{
ui.Dispatcher.BeginInvoke(new Action(SyncAction));
}
}
}
Надеюсь ненадо отдельно указывать про то что вместо this.Run() можно писать любой_UI_элемент.Run()
Если надо результаты успешной инициализации передать в UI поток, пользуйтесь замыканиями. Надо показать как?
A>Я могу часть элементов визуальных, относящихся к wpf, вынести в отдельный поток?
не нужно.
Re: wpf, выполнение действий в разных потоках
Здравствуйте, alex1010, Вы писали:
A>Есть, скажем, видеопанель, на которую выведены изображения от 5 ip-камер. Интерфейс построен на wpf.
A>При создании экземпляров камер/подключении к ним, возможны задержки до 15-20 секунд.
A>В результате, если тупо все делать в одно потоке, вся панель подвисает на это время, пока не пройдет инициализация камеры.
A>Логичное решение — вынести создание каждой камеры в отдельный поток.
A>Вопрос — на каком уровне это можно сделать?
На любом Делается так же как ина самом первом WPF:
Надеюсь ненадо отдельно указывать про то что вместо this.Run() можно писать любой_UI_элемент.Run()
Если надо результаты успешной инициализации передать в UI поток, пользуйтесь замыканиями. Надо показать как?
A>Я могу часть элементов визуальных, относящихся к wpf, вынести в отдельный поток?
не нужно.
A>Есть, скажем, видеопанель, на которую выведены изображения от 5 ip-камер. Интерфейс построен на wpf.
A>При создании экземпляров камер/подключении к ним, возможны задержки до 15-20 секунд.
A>В результате, если тупо все делать в одно потоке, вся панель подвисает на это время, пока не пройдет инициализация камеры.
A>Логичное решение — вынести создание каждой камеры в отдельный поток.
A>Вопрос — на каком уровне это можно сделать?
На любом Делается так же как ина самом первом WPF:
using System;
using System.Windows;
namespace WpfAsyncSample
{
using System.Threading;
using System.Windows.Threading;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Async(Action: () =>
{
// Долго инициализируемся и падаем
Thread.Sleep(2000);
this.RunSyncronously(() => label.Content = "Stage 1 done");
Thread.Sleep(3000);
this.RunSyncronously(() => label.Content = "Stage 2 done");
Thread.Sleep(4000);
throw new Exception("Stage 3 failed");
},
Then: optionalException =>
{
// Мы в UI потоке
if (optionalException == null)
{
// Всё ok.
}
else
{
// Инициализация упала.
}
});
}
}
public static class DispatcableExtentions
{
public static void Async(this DispatcherObject ui, Action Action = null, Action<Exception> Then = null)
{
if (Action == null)
throw new ArgumentNullException("AsyncAction");
ThreadPool.QueueUserWorkItem(state =>
{
Exception ex;
try
{
Action();
ex = null;
}
catch (Exception ex2)
{
ex = ex2;
}
if (Then != null)
ui.Dispatcher.BeginInvoke(new Action(() => { Then(ex); }));
});
}
public static void RunSyncronously(this DispatcherObject ui, Action SyncAction)
{
ui.Dispatcher.BeginInvoke(new Action(SyncAction));
}
}
}
Надеюсь ненадо отдельно указывать про то что вместо this.Run() можно писать любой_UI_элемент.Run()
Если надо результаты успешной инициализации передать в UI поток, пользуйтесь замыканиями. Надо показать как?
A>Я могу часть элементов визуальных, относящихся к wpf, вынести в отдельный поток?
не нужно.