Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.76/29: Рейтинг темы: голосов - 29, средняя оценка - 4.76
 Аватар для NapalmRain
44 / 43 / 7
Регистрация: 18.05.2010
Сообщений: 688
.NET 4.x

Запуск события из фонового потока для взаимодействия с основным

16.08.2019, 10:00. Показов 5782. Ответов 31
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго всем времени суток!

У меня есть некий класс, у него есть событие, на него подписано какое-то количество других классов.
Эти самые слушатели должны взаимодействовать по результатам события с UI, то есть что-то отображать на морде программы.

Класс же, который это событие возбуждает работает в фоновом потоке, там потенциально бесконечный цикл крутится и иногда должен сообщать о том, что у него что-то произошло.

С принципом работы событий я только начал разбираться по человечески, но к сожалению на этот гипотетический вопрос не смог найти ответа по интернетам.

Буду признателен за любой совет!
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.08.2019, 10:00
Ответы с готовыми решениями:

Вызов основного потока из фонового
Добрый день! Нужно выполнить некий код в отдельном потоке. По завершению выполнения, необходимо вызвать новую форму из ГЛАВНОГО...

Шаг ProgressBar не из фонового потока
Можно ли каким-то образом сделать шаг в ProgressBar'e если он создан в фоновом потоке, а я хочу вызвать функцию шага в другом потоке, можно...

Создание простейшего прелоадера при заполнении списка из фонового потока
Доброго всем времени суток! Задача, как мне кажется, для ну уж совсем новичков, но я, по непонятной мне причине, не смог найти вообще...

31
Эксперт .NET
 Аватар для Usaga
14092 / 9309 / 1349
Регистрация: 21.01.2016
Сообщений: 34,963
16.08.2019, 10:57
NapalmRain, что у WinForms, что у WPF для этого есть встроенные средства: Control.Invoke и Dispatcher.Invoke.
0
 Аватар для NapalmRain
44 / 43 / 7
Регистрация: 18.05.2010
Сообщений: 688
16.08.2019, 11:04  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
что у WinForms, что у WPF для этого есть встроенные средства: Control.Invoke и Dispatcher.Invoke.
Об этом я знаю, благодарю. Но обращаться к контролам или диспетчеку я бы не хотел.
Точнее даже не так, я хочу понять, можно ли это сделать из их помощи, именно только событиями
0
Эксперт .NET
 Аватар для Usaga
14092 / 9309 / 1349
Регистрация: 21.01.2016
Сообщений: 34,963
16.08.2019, 11:35
Лучший ответ Сообщение было отмечено NapalmRain как решение

Решение

NapalmRain, события не волшебство. Это коллекция методов делегатов, которые просто вызываются. С ними ничего не придумать.

Не хотите обращаться к контролами через Invok, есть другой, менее известный, подход - SynchronizationContext. Получаете текущий контекст (в GUI потоке), передаёте его коду, который должен что-то выполнить в GUI-потоке. Всё. Никакой завязки на UI.
1
 Аватар для NapalmRain
44 / 43 / 7
Регистрация: 18.05.2010
Сообщений: 688
16.08.2019, 11:42  [ТС]
Usaga, премного благодарен за разъяснения
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
16.08.2019, 13:14
NapalmRain, изучите интерфейс IProgress с классом Progress. И тогда не надо тяжких мучений.
https://docs.microsoft.com/ru-... attern-tap

Microsoft предложила всему мировому сообществу программистов на удивление правильную идею Task Asynchronous Pattern.
Так что чем больше прочитаете в блогах авторов данного паттерна (Стивен Тауб, Стивен Клири и другие),
тем больше будет понимания в смысле вот этого вот всего. Самое смешное, что придет понимание и в других языках программирования.
0
Эксперт .NET
 Аватар для Usaga
14092 / 9309 / 1349
Регистрация: 21.01.2016
Сообщений: 34,963
16.08.2019, 14:08
amr-now, асинхронность не заменяет многопоточности. Всё-таки разные вещи. А вот что класс Progress умеет имеет ивенты вызывать в контексте синхронизации я не знал.
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
16.08.2019, 14:15
Usaga, а Вы можете слёту дать определение асинхронности?

Чем больше думаю об этом, тем больше склоняюсь к определению, что асинхронность - разрыв единой непрерывной ленты исполнения инструкций на отдельные независимые куски. Каждый отдельный кусок называю "рабочий код". Кто-то называет "Job".
А как конкретно выполнять эти куски кода, имеет меньшее значение.
Можно:
- рядом на одной машине одновременно.
- на разных машинах одновременно.
- на одной машине как попало по очереди.

И всё равно мы попадаем под смысл асинхронности, потому что это всё разорванные куски кода, который мог быть монолитной лентой.
0
Эксперт .NET
 Аватар для Usaga
14092 / 9309 / 1349
Регистрация: 21.01.2016
Сообщений: 34,963
17.08.2019, 06:37
amr-now, это разделение потока исполнения на последовательность блоков кода, исполняющихся строго в том же порядке, в котором они идут в коде, как будто синхронно. Эти блоки могут исполнять в одном потоке (последовательно), но с разнесением по времени, или в другом потоке, но с сохранением порядка исполнения.

Смотрите на это как на событийную модель. По факту, это оно и есть. У вас работает код, встречает инструкцию await, запускает другую задачу (это не обязательно будет отдельный поток), подписывается на её завершение, сохраняет текущий контекст (в полях специально сгенерированного компилятором автомата) и отправляется выполнять какие-то другие дела. Когда запущенная задача завершится, на свет божий поднимется озвученный ранее автомат в котором сохранено прошлое состяние и исполнение продолжится с места, где мы преравлись ранее.

Т.е. это будет выглядеть так:
Ваш код А -> другая задача -> Ваш код Б -> Другая задача -> Ваш код В.

С точки зрения асинхронного метода, он будет работать синхронно: A, Б, В. Переходы к другим задачам сделаны прозрачно для вас. Как видите, ваш код исполняется строго последовательно, а где исполняются "другие задачи" вы сказать не можете. Это может быть и другой поток, а может быть и этот.

Почему это не подходит для задачи озвученной ТС-ом? Потому, что запускаемая задача должна завершиться полностью прежде, чем асинхронный метод сможет продолжить работу. У ТС-а же долгоиграющая задача, которой нужно репортовать о прогрессе своей работы. Это значит, что не можно сделать над такой задачей await, нарисовать её прогресс на UI, а потом продолжить await'ить тот же самый кусок кода.

Чтобы такое провернуть, код, где крутится длительная задача, придётся разбить на куски и вызывать асинхронно, а сам цикл, в котором это могло происходить, придётся вынести в асинхронный метод.

Примерно:
C#
1
2
3
4
5
6
7
// long running task in background thread
while(someCondition)
{
    // Long computation A
    _report.Report(); // Репортим, ожидаем, что UI обновится
    // Long computation B
}
Станет таким:
C#
1
2
3
4
5
6
7
// async method in UI thread
while(longTask.someCondition)
{
    await longTask.LongComputatoinA();
    updateUI();
    await longTask.LongComputatoinB();
}
Как видите, код сильно изменится и не в лучшую сторону. И это только при работе ОДНОГО фонового потока. Если их будет несколько, то начнётся возня с объединением Task'ов и await'ы уже этого дела.

Более того, await'ы в циклах не есть хорошо. Это не бесплатная операция.

Асинхронный код хорош своей краткостью и чистотой решений. А такая чистота достигается, когда вам из UI (или потока из пула ASP.NET) надо дёрнуть атомарную задачу, которая отработает и уйдёт в закат. Без всяких возобновляемых состояний.

Т.е. асинхронность никак и ничем не заменяет распараллеливание. Просто некоторые сценарии становится возможно исполнять более элегантно. С фоновыми задачами асинхронность никак не дружит и насильно их сдруживать не надо.
2
1152 / 860 / 263
Регистрация: 30.04.2009
Сообщений: 3,603
17.08.2019, 14:24
Цитата Сообщение от Usaga Посмотреть сообщение
на свет божий поднимется

Не по теме:

восстанет из пепла :D

0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
18.08.2019, 13:02
Usaga, сейчас перечитал Ваше сообщение. Мы с Вами пока одинаково очень плохо понимаем формулировку асинхронности.
Пытаюсь понять. Действительно, очень много переплетено с механизмом событий. Говоря философским языком, async/await и события являются изнанкой друг друга.
Народ всё пытается нащупать что и где лучше применить - TPL Dataflow, Rx или накостылить то же самое с async/await, или попытаться найти применение для AsyncEnumerator.
Очень много споров на эту тему и на Хабре и т.д.
0
Эксперт .NET
 Аватар для Usaga
14092 / 9309 / 1349
Регистрация: 21.01.2016
Сообщений: 34,963
19.08.2019, 07:06
amr-now, я действительно не смогу дать чёткое определение. Но
Цитата Сообщение от amr-now Посмотреть сообщение
TPL Dataflow, Rx или накостылить то же самое с async/await
... всё-таки разные вещи. Поддержка асинхронности в языке никак не заменяет многопоточность. Выше я попытался объяснить почему: не все сценарии возможно заасинхронить элегантным образом. Не стоит носиться с этой фичей как с новой приоритетной игрушкой. Если вам нужно какие-то атомарные задачи пинать и чтобы выглядело синхронно? async\await вполне может подойти. Нужна длительная фоновая операция? Асинхронность тут не в кассу.

Всё просто.
0
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
19.08.2019, 20:47
Это как давать определение текстовому файлу, который под капотом обычный бинарь. У меня свой вариант ->
Асинхронность - свойство кода возвращать управление до завершения вменяемой ему операции. Примеры:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Task WriteString()
{
    return Task.Run(() => Console.WriteLine("String"));
}
 
Task CreateHotTask()
{
    return Task.Run(() => Console.WriteLine("String"));
}
 
async Task CreateHotTask2()
{
    await Task.Run(() => Console.WriteLine("String"));
}
Все три метода асинхронно выполняют операцию по выводу строки на экран. Но асинхронным является только первый метод.
0
Эксперт .NET
 Аватар для Usaga
14092 / 9309 / 1349
Регистрация: 21.01.2016
Сообщений: 34,963
20.08.2019, 06:22
TopLayer, асинхронным является только метод CreateHotTask2 ибо последовательность выполняемых инструкций в его коде сохраняется в строгом порядке: сначала код до await, потом код в самом await, потом код после. Т.е всё исполняется как будто синхронно.

А вот первые два метода просто в параллель запускают вывод в консоль. То, что они Task возвращают асинхронности им не добавляет.
0
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
20.08.2019, 12:44
Цитата Сообщение от Usaga Посмотреть сообщение
асинхронным является только метод CreateHotTask2
Ну это по вашему определению...
Цитата Сообщение от Usaga Посмотреть сообщение
То, что они Task возвращают асинхронности им не добавляет.
Не утверждал обратного. Если у первого метода убрать возвращаемое значение, то он останется асинхронным.
Цитата Сообщение от Usaga Посмотреть сообщение
amr-now, это разделение потока исполнения на последовательность блоков кода, исполняющихся строго в том же порядке, в котором они идут в коде, как будто синхронно. Эти блоки могут исполнять в одном потоке (последовательно), но с разнесением по времени, или в другом потоке, но с сохранением порядка исполнения.
Получается, следующий код не является асинхронным?
C#
1
2
3
4
5
6
7
8
    private void btnSayHello_Click(object sender, EventArgs e)
    {
        Task.Factory.StartNew(() => this.Text = "Hello", 
            CancellationToken.None, 
            TaskCreationOptions.PreferFairness, 
            TaskScheduler.FromCurrentSynchronizationContext()
        );
    }
Цитата Сообщение от Usaga Посмотреть сообщение
исполняющихся строго в том же порядке, в котором они идут в коде, как будто синхронно.
Вот тут ошибка. Это признак отсутствия параллельности, а не критерий асинхронности.
Параллельность и асинхронность важно различать, но это не взаимоисключающие свойства.
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
20.08.2019, 13:33
Usaga, TopLayer, поэтому я как крымчанка и дочь офицера и говорю, что с параллельным программированием и асинхронным программированием не всё так однозначно.

Эту тему можно годами изучать...
0
Эксперт .NET
 Аватар для Usaga
14092 / 9309 / 1349
Регистрация: 21.01.2016
Сообщений: 34,963
21.08.2019, 07:23
Цитата Сообщение от TopLayer Посмотреть сообщение
Ну это по вашему определению...
Не совсем. Первые два метода работают синхронно. Без каких-либо нюансов. Это обычные методы. Последний заменяется компилятором на работу со структурой, представляющую собой автомат и содержащий все состояния этого метода: блоки кода разделённые операторами await. Эта структура эмулирует синхронное выполнение кода в методе, но с переключениями контекста потоков на время выполнения тасок в await. Это и есть асинхронный метод.

Цитата Сообщение от TopLayer Посмотреть сообщение
Не утверждал обратного. Если у первого метода убрать возвращаемое значение, то он останется асинхронным.
Ещё раз: в первых двух методах никакой асинхронности нет. Там просто запускается задача в потоке из пула. И задача эта исполняется параллельно коду в этих методах. Просто методы короткие. В последнем же методе, код "останавливается" на всех await'ах, пока задача в этом await'е не закончится. Т.е. код после await запустится по событию завершения задачи (или выбросится исключение, если что пошло не так). Огромная разница между этими методами. Вообще ничего общего.

Цитата Сообщение от TopLayer Посмотреть сообщение
Получается, следующий код не является асинхронным?
Да. Просто запускается поток. Код в этом методе не будет дожидаться завершения этого потока. Это параллельность, не асинхронность.

Цитата Сообщение от TopLayer Посмотреть сообщение
Вот тут ошибка. Это признак отсутствия параллельности, а не критерий асинхронности.
Никакой ошибки. Асинхронный код не параллельный. Так что всё верно. Инструкции в таком методе идут строго в том же порядке, что и описаны в теле метода. Код после await исполнится не раньше, чем завершится операция в операторе await. И не важно в каком потоке она будет исполнена.

amr-now, да, это разные вещи. Они не заменяют друг друга. О чём я и сказал с самого начала. Введение операторов async\await никак не заменяет потоки и потребности в долгих фоновых задачах.

Добавлено через 36 минут
Не обратил внимание на TaskScheduler.FromCurrentSynchronizationContext(). Лямбда выполнится в текущем потоке ПОСЛЕ того как завершится обработчик метода.
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
21.08.2019, 07:33
Товарищи, я единственный не вижу разницы между двумя методами?
C#
1
2
3
4
5
6
7
8
9
Task WriteString()
{
    return Task.Run(() => Console.WriteLine("String"));
}
 
Task CreateHotTask()
{
    return Task.Run(() => Console.WriteLine("String"));
}
Во всех трех методах "рабочий код" () => Console.WriteLine("String") выполняется в виде оторванной бумажки с последовательно исполняемыми инструкциями.
Конкурентность (Concurrency)? Асинхронность? Я пока НЕ понял различия.

А каким образом реализован запускач для оторванно исполняющегося "рабочего кода" - уже отдельный вопрос.

Без ключевого слова async это самый первичный метод, возвращающий Task.
C ключевым словом async реализуется уже вторичный метод-обертка, метод-декоратор, возвращающий Task.
(Причем оба варианта, вернее четыре с умножением на void, являются составляющими общей концепции Task Asynchronous Pattern.)

На заметку - до первого await любой метод выполняется синхронно. (Опять же - исполнение оторванной бумажки "рабочего кода" не является исполнением метода-запускача этого "рабочего кода").
0
Эксперт .NET
 Аватар для Usaga
14092 / 9309 / 1349
Регистрация: 21.01.2016
Сообщений: 34,963
21.08.2019, 07:35
Цитата Сообщение от amr-now Посмотреть сообщение
Товарищи, я единственный не вижу разницы между двумя методами?
У них название разные.

Цитата Сообщение от amr-now Посмотреть сообщение
Конкурентность (Concurrency)? Асинхронность? Я пока НЕ понял различия.
Параллельно с текущим методом или нет. В этом различие.
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
21.08.2019, 07:43
Цитата Сообщение от Usaga Посмотреть сообщение
Параллельно с текущим методом или нет. В этом различие.
Для await абсолютно без разницы, где и когда осуществляется исполнение оторванных бумажек "рабочего кода".
- по очереди в хаотическом порядке.
- одновременно в одном процессе, но в разных threads.
- одновременно в разных процессах одного компьютера.
- одновременно на разных компьютерах.

Но await - это не единственый признак асинхронности. Ещё есть старый добрый Event Asynchronous Pattern (EAP). И даже асинхронный паттерн на функциях обратного вызова, не к ночи они будут упомянуты.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.08.2019, 07:43
Помогаю со студенческими работами здесь

Получение значения из фонового потока и передача его в главный поток
как получить значение из фонового потока и передать его в главный поток?Знаю что метод должен быть только void...

Запуск потока для функции с параметрами
Доброго дня! Что хочется: распараллелить выполнение процедуры func. Давая новым потокам соответствующие параметры. На c# я...

Способ вызова из фонового потока метода, но чтобы последний выполнялся в главном потоке
Есть два потока: главный и фоновый. Ищу способ вызова из фонового потока метода, но чтобы последний выполнялся в главном потоке. ...

Запуск Process: Операция асинхронного чтения для потока уже запущена
Здравствуйте Программа такая есть кнопка и есть textbox при нажатии на кнопку выполняется вызов ipconfig , читается вывод который...

Реализуйте запуск потока для последовательного счета, начиная с заданного числа
Доброго времени суток Задание такое: Реализуйте запуск потока для последовательного счета начиная с заданного числа (создать функцию ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru