русский
Germany.ruForen → Архив Досок→ Programmierung

Непонятно с async-await в C# - 2

02.09.21 21:15
Re: Непонятно с async-await в C# - 2
 
alex445 свой человек
in Antwort Бесконечный цикл 02.09.21 20:28, Zuletzt geändert 02.09.21 21:39 (alex445)

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


Или, как вариант, программисты слишком глубоко копают, что многим из них не нужно. Как я понял, с async/await важно знать только, что это необязательно выполняется в другом потоке (т.е. это не многопоток в чистом виде), и чего с ними можно делать, а чего нельзя. И несколько use cases. Лезть внутрь - вот зачем? Ну выкитал там в видео человек портянку какого-то странного кода. Я что, чтобы работать с async/await, должен эту и другие подобные портянки всегда в голове держать, и всегда прогонять свой код использования async/await через эти портянки - а что там внутри мол произойдёт? Проще иметь список абстрактных правил, если эти абстракции не сильно протекают. Ну это типа как просто водить машину, и уметь подшаманить там что-нибудь самому. Оно конечно полезно - уметь самому, но нахрена оно мне надо, если я программист, а нифика не автомеханик, ни слесарь, и у меня даже хобби такого нет - торчать под машиной? Вон джаваскриптеры вообще не знают, когда у них какого типа данные, и что получается при разных манипуляциях с ними - и ничё, нормально живут, бабки зарабатывают не меньше всяких шарперов, а работы и вакансий у них на порядок больше, чем у этих шарперов.


Возможно, просто раньше были хреново написаны тьюториалы. Да и сейчас, как я понял, вся эта инфа раскидана по нескольких разделам, а не собрана в одном месте.


Но в любом случае, async/await не заменяет нормальную работу с потоками (Thread, lock, всякие MemoryBarrier и прочее). Даже, пожалуй, наоборот - если ты хорошо знаешь, как работать с потоками и писать потокобезопасный код, ты можешь вообще без async/await обходиться, а просто загонять всё явно в другие потоки и "вручную" синхронизировать их.


Я в своей программе делал проще. У меня в реальном времени с платы сбора данных поступали данные. Их надо было обсчитывать, надо было результаты обсчётов в реальном времени выводить на графики и обновлять показания в интерфейсе. Я сделал что-то вроде конвейера. Приходящие данные с платы записывались в массив в одном потоке - этот поток постоянно опрашивал порт и считывал из него новые данные. Другой поток брал сохранённые в предыдущий массив данные, делал первоначальную обработку и сохранял в другой массив. Тут не нужна была синхронизация и блокировки, т.к. один поток только писал в массив, а другой только читал из него же, отслеживая новые данные по размеру массива и последнего прочитанному индексу, и записывал результаты в следующий массив. Ну и так далее - было что-то около 3-4 таких "уровней". Ещё один поток брал данные из последнего массива, делал окончательный расчёт и сохранял в специальные структуры результатов - тоже в виде массива. Следующий поток данные из этих структур брал и обновлял интерфейс. И все эти потоки молотили постоянно - на каждом уровне обработки данных я опрашивал размер массива из предыдущего уровня - не увеличился ли он достаточно, чтобы набрать очередной пакет данных для расчёта. И я эти потоки разве что притормаживал через тупой Thread.Sleep(), т.к. постоянный опрос массива в бесконечном цикле естественно займёт ядро процессора на 100%.


Тогда я столкнулся с плохой производительностью графической системы из-за его так называемой retained model (я достаточно глубоко копаю?) и странной логикой отрисовок.

Там ещё ссылки есть на интересные статьи и видео

Introducing Direct2D | Microsoft Docs (искать по слову "retain")

Michael Wallent: Advent and Evolution of WPF | Charles | Channel 9 (msdn.com)


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

 

Sprung zu