wpf, выполнение действий в разных потоках
От: alex1010  
Дата: 07.07.16 08:47
Оценка:
Есть, скажем, видеопанель, на которую выведены изображения от 5 ip-камер. Интерфейс построен на wpf.
При создании экземпляров камер/подключении к ним, возможны задержки до 15-20 секунд.
В результате, если тупо все делать в одно потоке, вся панель подвисает на это время, пока не пройдет инициализация камеры.
Логичное решение — вынести создание каждой камеры в отдельный поток.

Вопрос — на каком уровне это можно сделать? Я могу часть элементов визуальных, относящихся к wpf, вынести в отдельный поток?
Или все что касается визуального интерфейса wpf нельзя запихивать в созданный вручную, отдельный thread?
Просто код, где идет инициализация камеры, наворочен и не хочется туда лезть его переделывать.
Re: wpf, выполнение действий в разных потоках
От: b0r3d0m  
Дата: 07.07.16 09:04
Оценка:
A>Или все что касается визуального интерфейса wpf нельзя запихивать в созданный вручную, отдельный thread?
Нельзя.
Re: wpf, выполнение действий в разных потоках
От: Glas  
Дата: 07.07.16 11:58
Оценка:
Здравствуйте, alex1010, Вы писали:

A>Вопрос — на каком уровне это можно сделать? Я могу часть элементов визуальных, относящихся к wpf, вынести в отдельный поток?


Если от камер есть эвенты, то можно. Создаете интерфейс — главный поток, в нем инициализируете потоки камер, ловите из них события. НО надо через диспетчер перекидывать выполнение эвентов в главный поток.
Re: wpf, выполнение действий в разных потоках
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 07.07.16 12:08
Оценка: 1 (1)
Здравствуйте, alex1010, Вы писали:

A>Есть, скажем, видеопанель, на которую выведены изображения от 5 ip-камер. Интерфейс построен на wpf.

A>При создании экземпляров камер/подключении к ним, возможны задержки до 15-20 секунд.
A>В результате, если тупо все делать в одно потоке, вся панель подвисает на это время, пока не пройдет инициализация камеры.
A>Логичное решение — вынести создание каждой камеры в отдельный поток.

A>Вопрос — на каком уровне это можно сделать? Я могу часть элементов визуальных, относящихся к wpf, вынести в отдельный поток?

A>Или все что касается визуального интерфейса wpf нельзя запихивать в созданный вручную, отдельный thread?
A>Просто код, где идет инициализация камеры, наворочен и не хочется туда лезть его переделывать.

http://ru.stackoverflow.com/questions/514529/%d0%97%d0%b0%d0%b2%d0%b8%d1%81%d0%b0%d0%b5%d1%82-%d0%be%d0%bf%d0%b5%d1%80%d0%b0%d1%82%d0%be%d1%80-await-%d0%b2-%d0%be%d0%ba%d0%be%d0%bd%d0%bd%d0%be%d0%bc-%d0%bf%d1%80%d0%b8%d0%bb%d0%be%d0%b6%d0%b5%d0%bd%d0%b8%d0%b8-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%b0-%d0%b2%d0%b8%d1%81%d0%b8%d1%82-%d0%bf%d1%80%d0%b8-%d0%b2%d1%8b%d0%b7%d0%be%d0%b2%d0%b5-task/514533#514533
и солнце б утром не вставало, когда бы не было меня
Re: wpf, выполнение действий в разных потоках
От: b0r3d0m  
Дата: 07.07.16 18:07
Оценка: +1
Выполняйте максимум действий, не связанных с UI, в своих потоках, а при необходимости работы с UI вызывайте Dispatcher.Invoke / Dispatcher.BeginInvoke.
Re[2]: wpf, выполнение действий в разных потоках
От: alex1010  
Дата: 14.07.16 12:35
Оценка:
Здравствуйте, b0r3d0m, Вы писали:

A>>Или все что касается визуального интерфейса wpf нельзя запихивать в созданный вручную, отдельный thread?

B>Нельзя.

Тут все дело в том, что получение видео с камеры делает наш модуль и у нас уже есть видео-панель, без исходников, которая хоть и кривоватая, но не подвисает, пока камера тормозит, пытаясь через synhronizationContext вывести что-то на экран.
Как видеопанель это делает? хз.
Re[2]: wpf, выполнение действий в разных потоках
От: alex1010  
Дата: 14.07.16 12:42
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>http://ru.stackoverflow.com/questions/514529/%d0%97%d0%b0%d0%b2%d0%b8%d1%81%d0%b0%d0%b5%d1%82-%d0%be%d0%bf%d0%b5%d1%80%d0%b0%d1%82%d0%be%d1%80-await-%d0%b2-%d0%be%d0%ba%d0%be%d0%bd%d0%bd%d0%be%d0%bc-%d0%bf%d1%80%d0%b8%d0%bb%d0%be%d0%b6%d0%b5%d0%bd%d0%b8%d0%b8-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%b0-%d0%b2%d0%b8%d1%81%d0%b8%d1%82-%d0%bf%d1%80%d0%b8-%d0%b2%d1%8b%d0%b7%d0%be%d0%b2%d0%b5-task/514533#514533


интересно, но как это поможет решить проблему, не понял (

Bar().Wait();
await Task.Delay(1000); // здесь как бы вывод на экран
такого в нашем коде и нет — нет Wait, о котором статья.

Просто использование await не работает, т.к в этом await идет отрисовка через synhronizationContext UI. И когда там подвисает, то подвисает и все приложение.
При этом имеющаяся видеопанель как-то ухитряется не виснуть, хотя код модуля с await тот же самый.
Re[3]: wpf, выполнение действий в разных потоках
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 14.07.16 13:26
Оценка:
Здравствуйте, alex1010, Вы писали:

A>Здравствуйте, Serginio1, Вы писали:


S>>http://ru.stackoverflow.com/questions/514529/%d0%97%d0%b0%d0%b2%d0%b8%d1%81%d0%b0%d0%b5%d1%82-%d0%be%d0%bf%d0%b5%d1%80%d0%b0%d1%82%d0%be%d1%80-await-%d0%b2-%d0%be%d0%ba%d0%be%d0%bd%d0%bd%d0%be%d0%bc-%d0%bf%d1%80%d0%b8%d0%bb%d0%be%d0%b6%d0%b5%d0%bd%d0%b8%d0%b8-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%b0-%d0%b2%d0%b8%d1%81%d0%b8%d1%82-%d0%bf%d1%80%d0%b8-%d0%b2%d1%8b%d0%b7%d0%be%d0%b2%d0%b5-task/514533#514533


A>интересно, но как это поможет решить проблему, не понял (


A>Bar().Wait();

A>await Task.Delay(1000); // здесь как бы вывод на экран
A>такого в нашем коде и нет — нет Wait, о котором статья.

A>Просто использование await не работает, т.к в этом await идет отрисовка через synhronizationContext UI. И когда там подвисает, то подвисает и все приложение.

A>При этом имеющаяся видеопанель как-то ухитряется не виснуть, хотя код модуля с await тот же самый.

await Task.Delay(1000).ConfigureAwait(false); // Не блокирует и заканчивает поток в том потоке в котором и вызван.


Создавай задачи, главное, что бы они использовали внутри асинхронные методы только с ConfigureAwait(false);
Иначе получишь взаимную блокировку.

http://ru.stackoverflow.com/questions/512968/win10-universal-app-async-%d0%b7%d0%b0%d0%b4%d0%b5%d1%80%d0%b6%d0%ba%d0%b0/513241#513241
и солнце б утром не вставало, когда бы не было меня
Отредактировано 14.07.2016 13:55 Serginio1 . Предыдущая версия . Еще …
Отредактировано 14.07.2016 13:54 Serginio1 . Предыдущая версия .
Re[4]: wpf, выполнение действий в разных потоках
От: alex1010  
Дата: 14.07.16 15:52
Оценка:
Здравствуйте, Serginio1, Вы писали:
S>
S>await Task.Delay(1000).ConfigureAwait(false); // Не блокирует и заканчивает поток в том потоке в котором и вызван.
S>


S> Создавай задачи, главное, что бы они использовали внутри асинхронные методы только с ConfigureAwait(false);

S>Иначе получишь взаимную блокировку.

S>http://ru.stackoverflow.com/questions/512968/win10-universal-app-async-%d0%b7%d0%b0%d0%b4%d0%b5%d1%80%d0%b6%d0%ba%d0%b0/513241#513241


я запустил обращение к камере в своей видеопанели таким образом (из UI потока)
await Task.Run( cam1 ).ConfigureAwait( false );
и она подвисла на пару десятков секунд. Т.к внутри cam1 идет доступ к отрисовке UI и пока не закончится, не отвисает. ConfigureAwait не помогает.

Такое впечатление, что имеющийся другой видеоплеер как-то ловит SynchronizationContext.Send и вручную что ли распределяет..
Re[5]: wpf, выполнение действий в разных потоках
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.07.16 10:41
Оценка: +1
Здравствуйте, alex1010, Вы писали:


A>я запустил обращение к камере в своей видеопанели таким образом (из UI потока)

A>await Task.Run( cam1 ).ConfigureAwait( false );
A>и она подвисла на пару десятков секунд. Т.к внутри cam1 идет доступ к отрисовке UI и пока не закончится, не отвисает. ConfigureAwait не помогает.

Ну обычно данные сначала подготавливаются, а потом выводятся
и солнце б утром не вставало, когда бы не было меня
Re: wpf, выполнение действий в разных потоках
От: VladCore  
Дата: 23.07.16 22:02
Оценка:
Здравствуйте, alex1010, Вы писали:

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, вынести в отдельный поток?


не нужно.
Отредактировано 23.07.2016 22:30 VladCore . Предыдущая версия . Еще …
Отредактировано 23.07.2016 22:27 VladCore . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.