Отличное объяснение. По делегатам действительно нет ни одного нормального объяснения, только видел пример на коллекции (посчитать к примеру сумму элементов с доп фильтром допустим только четные и т.п.). Эти доп фильтры делать делегатами, и в основном коде вызывать нужный делегат. Но этот пример не живой, ведь вместо всего этого можно использовать лямбда-выражения или вообще LINQ. Другой пример, который встречал - это применение делагатов в обратных вызовах, но там опять же у нас есть события. Т.е. делегаты в чистом виде в нормальном коде не встретишь.
Вы когда-либо с Event-ами работали? Там делегаты очень применимы. Эдакое сюрное объяснение "с потолка", но когда случится что-то такое делать, оно само по идее в голову придёт, что нужен такой механизм. Так вот пример: Я -- создатель некоторого события "раздача плова в тарелочке с вилочкой" и я раздаю плов, а ко мне приходят люди за пловом в тарелочке и за вилочкой. Эти люди -- делегаты. И вот я раздаю весь такой, а что будет дальше с этим пловом и одноразовой посудой я класть хотел, а люди-то разные: один съест, другой сделает себе из тарелочки воображаемую шапочку, третий обмажется пловом, четвёртый пойдёт мастерить из него взрывчатку... Но твоя (моя т.е.) задача не меняется, я всего лишь раздаю это. А ещё более просто и реально -- это, собственно, о делегировании обязанностей в реальном мире. Например: Вы - интернет-магазин. Вы продаёте товары и Вы ведёте доставку курьерами. Вы формируете заказы к отправке, а куча курьеров их доставляют, но Вася на велосипеде, Петя общественным транспортом, Вова на машине, а Дима вообще рулит большой почтовой службой и выполняет авиа-перевозки. Третий пример: отправка 1 оповещения (новости) в разные соц-сети одной кнопкой. Вы указали, что на событие реагируют только делегаты, принимающие такой-то набор параметров, из которых состоит ваша новость, например (заголовок и содержание) и всё, море обработчиков может обрабатывать эти данные и заниматься их публикацией каждый в своей соц-сети. Издатель же новости в свою очередь лишён головной боли о том как же эту новость опубликовать везде. Он делегировал эту обязанность другим, и эти другие -- делегаты.
@@absamurai про интернет-магазин прям из языка снял. Вот пример с рынком: тебе нужна малина? Ты идешь на рынок(к примеру) или в любое удобное место где её можно купить. Ты не идешь на огород и не обращаешься к владельцу производства потому что это неудобно. Так вот тетя Зина - это делегат.
Делегаты придумали именно для событийного программирования. Смысл в том что делегат может иметь множество ссылок на разнице методы (техника подписки и отписки на собитие, хотя в обёртке события самый обычный делегат). Главное что бы сигнатура подходила. + Лямбда выражение (тоже делегат предикат). Так то все делегаты уже придуманы свои пишешь если не знаешь системного. Такие как Action, Func, Predicat, и т.д. Урок хорош!)
Мне приходилось использовать делегаты, чтобы обновлять значения в режиме реального времени в таблице datagridview в WinForm. Было клиент-северное приложение, на клиенте был запущен поток, который получал данные от сервера и заносил инфу в таблицу. Код обновления данных в таблице выполнялся внутри делегата, иначе возникла ошибка, точное описание не помню, но че то там с доступом. Ниже приведен упрощенный фрагмент кода, где использовался делегат. private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) // получить данные { while (client.Connected == true) // пока клиент подключен { lock (locker) // для синхронизации потоков { // получение и обработка данных this.Invoke(new MethodInvoker(delegate { // обновление данных в таблице })); } }; }
ХрисТ, ты даже не представляешь себе какой ты молодец. Тебя очень приятно слушать и многие вещи становятся понятнее, чем раньше. Знать и донести это две разные вещи и ты владеешь обоими.
Просмотрел все уроки. Всё понятно, кратко и по существу. Большое спасибо. Если есть возможность, сделай урок по проблематике защиты кода от дизасемблеров и вообще насколько вероятно сохранить алгоритм программы в секрете.
Вот это объяснил))). Сколько видосов про потоки смотрел, этот прям с первого раза зашел. Прям все по человечески объяснил, на простом языке. Спасибо. С меня лайк и подписка
Для меня самое простое объяснение делегата - ссылка на метод или список ссылок на группу методов. Нужны они для удобства, когда какое-то событие может вызывать различные методы, которые в свою очередь определяются в рантайме, а не на стадии компиляции. В зависимости от каких-то условий или действий пользователя мы можем вызвать тот или иной метод, а так же целый список методов, меняя его при необходимости. Написал все нужные методы, а потом просто тупо добавляешь на них ссылку в делегат или убирай из него. Может плюсы делегатов не особо очевидны, когда метод один и он либо вызывается событием, либо нет и третьего не дано. Но когда присутствует большая вариативность поведения, то делегаты могут очень помочь.
Да, абсолютно верно, наконец-то я тоже до этого допёр!) В данном видео не показана одна важная функция делегатов - это расширения списка методов делегата через простую операцию «+=». Это супер удобно при работе в рантайме
Обычно, подобные уроки ставлю на скорость воспроизведения х1.5 или х2. Тут я впервые захотел чуть понизить скорость подачи :) А в целом круто, четкий грамотно сформулированный поток инфы. Думаю это максимум, что можно уложить в 30 минут, так что за более подробным и вдумчивым перевариванием нужно идти читать документацию. Спасибо за труд!
К делегатам добавлю некоторое пояснение. Да делегат в простом варианте является конвертером члена класса "метод" в объект, что-бы с методом можно было обращаться как с любым другим объектом (перемеренные, поля, свойства, параметры и тд.). Делегаты из таких структур появились достаточно рано и стали базисом для последующего синтаксического сахара такие как анонимные методы (как мы собираемся обращаться к анонимному методу если у него нету имени), лямбда-выражения (немного функционального программирования из F# и Омега# в C# которые просто красиво написанные анонимные методы) и типы делегаты Action(0...P16) и Func(return,0...P16) (очень сильно упрощают жизнь если нужны всевозможные колбеэки и актуаторы и последнее это события (события и есть делегат только более красиво написанный, события можно и на чистых делегатах написать, толком разницы нету кроме красивости кода). А живой пример смотри на само слово делегат что в переводе на русский является представитель по типу торговых представителей (орифлеймы всякие), послы в посольствах государственных по нормальному это государственные представители и так далее. Если что-то как-то надо представлять каким либо образом это вот делегат. А так это выросло из шаблона проектирования который так и называется делегат (иногда как шаблон делегирования)
По моему, необходимость делегатов хорошо объясняет паттерн "Стратегия". Пример такой: У тебя есть определённая стратегия работы. Например: строительство коттеджного посёлка. И у тебя есть проекты строительства домов, дома все похожие, отличаются только в мелочах. Одна из задач в каждом проекте - выкопать котлован под фундамент. Так вот, в каких-то случаях ты можешь загнать туда чернорабочих, и они выкопают (т.к. например, экскаватор туда не проедет). В другом случае на эту же задачу ты отправишь мини-экскаватор. В третьем случае ты отправишь мощный экскаватор с отбойником, (т.к. там к примеру, там находится особо крепкий грунт). Так и в программировании - у нас есть общий метод, с командами - выкопать фундамент, подготовить основание, сделать опалубку, залить фундамент и т.д. а какими методами ты будешь строить каждый конкретный дом - зависит от конкретной ситуации, которая задаётся в конкретном случае и с конкретными условиями.
Я постоянно не мог найти инфу по этому всему, пытался нарыть инфу из самых странных источников, но тут нашел это видео, и просто любовь с первого взгляда
Делегат - можно понимать как callback функцию. Строготипизированный колбек дает большую гибкость. Во в первых - он гарантирует, что переданная лямбда соответствует сигнатуре, во вторых - внутри своего метода он позволяет на основании своей сигнатуры писать корректный в плане типов код, что помогает не заниматься отладкой 8 часов, в третьих - не обязательно в метод передавать лямбду, хоть иногда это, безусловно, удобно. list.Sort((a, b) => a.Id.CompareTo(b.Id)) например можно заменить на list.Sort(Sort.ById). Делегаты очень широко используются в мире функционального программирования, да и в классическом ООП (например, паттерн шаблонный метод)
У меня есть бутылка и она закрытая. "Открытие крышки" - вот наш делегат!. Мы можем открыть эту бутылку нормальным способом, а можно - ложкой; можно зубами тоже (если они здоровые), некоторые могут и глазом.
Про делегаты. Предположим есть комната в которой нет ни окон ни дверей, задача в ней убраться: пропылесосить, протереть пыль. Для решения нужен тот кто уберет комнату и способ в эту комнату попасть. Представим что у нас есть Маша, Петя и Вася - все они могут убрать комнату. Теперь надо их в комнату как-то поместить, есть два варианта: 1) для каждого из них прорубить отдельный вход; 2) сделать ДВЕРЬ.
Предположим, что Маша, Петя и Вася хотят покушать. Есть вариант каждому кушать из своей тарелки, а можно кушать просто с КАСТРЮЛИ. Нет, не годится. Жду новых примеров. Кстати, после выхода этого видео, спустя какое-то время нашёл применение делегату - доступ к контролу из класса. Это боль...
@@XpucT Вопрос изначально был зачем? Ну он же вроде как для соплей) Ну типа есть 15 алгоритмов сортировки массива и какой-нибудь PrintTime() для подсчета времени работы каждого алгоритма. Мы делаем PrintTime(Action ... ) и норм, нет? Подобие функциональной обертки из плюсов.
По делегатам, строим аналогию с C++. Функцию нельзя напрямую передать в функцию в качестве параметра. Но можно передать указатель (адрес, "делегат") / Даже в C++ не рекомендуют, в настоящее время, использовать указатели на функцию, а использовать класс Functional - аналог лямбда выражений в C#.
Спасибо, перевел свой софт для сжатия игр во много поток, ускорил работу в 2-5 раз) Я еще использовал сплит списка строк, на мини списки по 3 элемента, чтобы обработка шла, в каждом потоке по 3 элемента, вместо всех элементов в одном потоке) Мозг лопнул, но по кайфу работает
Про делегаты приведу пример. Есть метод который вызывается для заполнения progressBar, и вот у нас где-то там в другом классе, в другом пространстве имен есть метод который считывает огромный файл, и для этого мы создадим делегат и передадим как параметр, чтоб увидеть прогресс выполнения/чтения файла. Для событий без делегатов не обойтись
20:42 "New Thread, Старт! *Погнал*" Чет ору с этого, ахахахахахахахахахахахахахаха. Забавно вы это говорите и когда представляешь тоже ситуация забавная! (типа слишком быстро) Рождается и ему сразу старт, и он погнал
Использовал делегат чтобы на одну кнопку вешать 2 метода(старт/стоп), т.е. кнопка вызывает делегат ,а дальше в методе к ему привязывается другой метод и второй клик по кнопке уже для совсем других действий. Может можно было реализовать проще, но это первое что в голову пришло)
Спасибо за видео! Отлично всё разъяснено в ролике. Планируете ли снимать ролики по алгоритмам, паттернам? Было бы здорово коснуться темы DI, IoC -контейнеров.
По поводу делегатов и директора как раз все понятно. Ты обращаешься именно не к человеку, а к тому, кто выполняет обязанности директора. Если директор в отпуске, за него ответит зам или секретарь, или хз кто. Тебе не важно, кто именно, какой именно человек, главное, чтобы он был уполномечен. А лямбда оператор - это всего лишь синтаксический сахар.
очень круто, многое понял! Осталось понять как сделать поток который бы выполнял задачи по записи и чтению файлов и передавал их в основной поток (привет из Unity и Monobehavior работающих в основном потоке)
Мне понравилось объяснение про ружье и звонок)) А я когда проходил делегаты думал что если я не понимаю его применения на практике, то я че-то не так понял и вообще тупой)
Очень доходчиво объясняешь, скобки правильно расставляешь, так лучше, чем в строку. Юмора как раз столько, сколько надо) Если возможно - уменьши область захвата видео до размера окна виртуалки, т.к. мелкие символы на 720P не видно нормально (Инет 3G, живу вдали от цивилизации)
Присоединяюсь ко всем словам благодарности. Спасибо за проделанную работу! Хочу дать обратную связь. (13:09) В строчку или в столбик записан код на экране не очень принципиально. Есть только одно пожелание. Увеличьте, пожалуйста, размер шрифта кода. Если смотреть с телефона, то почти ничего не видно. Спасибо!) PS. На 150% увеличении комфортно (15:35) 🙂
спустя 5 лет опять смотрю это видео. Столько событий произошло, а я заново пытаюсь вкатиться. Сейчас хотя бы работу нашел, но опять наткнулся на делегаты.
Делегат это шаблон обертки для методов определенной сигнатуры указанной в определении делегата. После создания экземпляров делегатов в них можно помещать методы соответствующей сигнатуры. Также экземляры делегатов можно складывать и вычитать, при этом будут добавляться и удаляться методы внутри них. Зачем это надо? Ну, например для событий. Событие это по сути и есть делегат, обернутый в виде свойства. Можно добавлять в него ссылки на методы(подписываться) и удалять(отписываться). Компилятор создает делегаты неявно когда вы передаете лямбду в метод или подписываете метод на событие. Все делегаты имеют метод Invoke() который их вызывает. По сути делегаты это удобный метод хранения ссылок на методы и работы с ними. Грубо говоря как Object для переменных, только делегаты для методов.
Спасибо огромное за урок, очень классное объяснение. Насчёт написания кода, как по мне, то в строчку лучше, и понятнее. Ещё вопрос, есть ли урок работе с процессами, и сетевое программирование ?
Живой пример использования делегатов. Вам нужно решить систему из 100 дифференциальных уравнений вида dy/dx =F(x, y1....y100). Правые части системы - функции F записываются как массив делегатов одинаковой сигнатуры. Но начинка внутри каждой функции - разная. Программа видит делегат и вызывает функцию нужного содержания с заданным набором аргументов. Это как указатель на функцию в С.
делегат удобен тогда, когда тебе нужен список делегатов (то-есть у тебя есть методы 1,2,3,4,5,6,7) и ты хочешь их выполнять, у тебя есть список с этими методами типа хочу чтобы, выполнялись так 1,2,3,2,2,2,2,2,1,3,4,5 и ну это можно когда количество небольшое прописать вручную, а так существуют делегаты которые можно добавить в список и выполнять когда тебе нужно и в любой последовательности (станки чпу, сценарии какие-то)
Спасибо за видео друг ! и Коту привет ! Вопрос . Запустить поток можно так: поток.Start(); а есть ли возможность остановить выполнение потока когда мне нужно ? или как "убить" поток в процессе работы программы ? Спасибо !
По поводу делегатов, в основном используется другая их форма - события. Ну то есть события и есть делегаты, только более продвинутые. Ну уж я надеюсь, что никто не отрицает полезность событий)
Из того что знаю я deligate нужен как атрибут метода. Такой метод не имеет тела и нужен он чтобы запомнить сигнатуру. Например () когда есть коллекция свойств с разными атрибутами и у нас есть метод который возвращает все свойства с одним атрибутом, все свойства с другим и так далее...В этому случае можно написать метод обертку в который передается параметром коллекция и делигативный метод, который проверяет свойство на причастность к атрибуту. И тогда у нас будет не N методов по все атрибутам, а только 2 : один делигат и метод этот делигат использующий. Конкретно в тредах делигат видимо используется для того чтобы передать сигнатуру метода.
Делегаты нужны для того, чтобы различные функции в качестве аргументов передавать в другие функции, чтобы потом эти переданные в качестве аргументов функции вызывались когда угодно, идеальный пример - конвейер компонентов Middleware для Asp.Net Core. Если ошибаюсь, поправьте
По поводу примера из жизни про делегаты. Жили-были крестьяне, которых царское самодержавие сильно угнетало. И тут приходит Ленин со своей советской властью. Крестьяне обрадовались, что сейчас им Ленин этой самой земли-то и прибавит. Вот только как об этом сказать Ленину? Есть вариант: каждый из крестьян идёт к Ленину и говорит: "Владимир Ильич, я крестьянин Иванов (Петров, Сидоров), мне бы земли побольше". Потом они почесали репу и решили, что так не пойдёт. Это получается, что вся деревня отправится в Петроград. Тут и красноармейцы по дороге могут остановить и расстрелять (ибо любая власть боится толпы народа), да и работать на земле кому-то нужно. Вот крестьяне и решили отправить Ленину одного Пахома. Так и говорят: "Ты, Пахом, будешь нашим делегатом. Как Ленин тебя спросит, мол, зачем пришёл, ты изложишь ему нашу задачу". Тут Иванов кричит: "и про меня не забудь". И Петров ему вторит: "и про меня тоже". Так все крестьяне дружно подписались на делегат. Чтобы как Ленин подписал свой указ, так чтобы он на всех распространился, кто к нему Пахома отправил.
С await не понял, как работать. Есть код. К примеру, хочу чтобы что-то при нажатии на button выполнялось асинхронно. И хочу чтобы там же менялся текст в label1. async private void button1_Click(object sender, EventArgs e) { await Task.Run(() => { // какой-то код // обработка потока при Debug BeginInvoke((MethodInvoker)(() => { label1.Text = $"Число {result} является Doubleton"; label2.Text = "Результат готов"; })); }); } Но при таком коде ошибки в Debug нет, но зато вся асинхронность просто улетучивается. Более того асинхронность перестает работать даже в релизе без отладки. Пробовал и с action и с просто Invoke, что я делаю не так? :) И спасибо за видео !!!
Допустим у нас имеется прибор, подключеный к ПК через COM порт (USB). И необходимо через протокол (не важно какой) отправлять на него данные, а также обрабатывать его ответы. С визуальной составляющей, используя Forms, проблем возникнуть не дожно. Вопрос состоит вот в чем: можно ли при помощи C# и Visual Studio Community создать программу, которая будет контролировать входные и управлять выходными данными (последовательности байтов согласно выбраному протоколу) COM порта, к которому подключен прибор ?
Делегат это ссылка на метод (функцию, порядок неопределённых действий) который будет использован в классе или методе. Когда это может быть полезно? Когда хочешь сделать код универсальным без модификаций имплементации основного класса и в тоже время сделать код более компактным. LINQ прекрасный образчик универсальности. Например: вы вычисляете остаток по кредиту за период. вы можете всё сделать просто: в одном методе. а можете в определенный момент(как параметр метода или как атрибут класса) передать функцию по вычислению процента по кредиту какому-то пользователю класса. При этом вам не надо наследовать класс (в C# можно наследовать только от одного класса). Вы даже можете сделать ваш класс закрытым для модификации. По моему скромному мнению: В каком-то смысле делегаты(ссылка на метод) противопоставляет себя одному из принципов ООП: инкапсуляции.
Обожаю c#, пользуюсь 2008 студией, потому что не люблю выкачивать тонны гигабайт и люблю легкие ide, уже тогда было столько фичей в нем. Тогда наверное он казался языком из будущего.
А вот у вас на 14:26 в режиме Release меняется lable а у меня почемуто не меняется и выдает ошибку. System.InvalidOperationException: "Недопустимая операция в нескольких потоках: попытка доступа к элементу управления 'label1' не из того потока, в котором он был создан." Тоже запускаю в Release. С чем это может быть связано?
Решение ➜ Очистить решение. Либо перезапустить проект. Но в Release такого не должно быть. Если ошибка повторяется, начните сначала или создайте чистый проект. Где-то тогда Ваш косяк.
@@XpucT Спасибо за ответ. Извините что заставил обратить на себя внимание. В новом проекте такая же борода. Очистить решение не помогло. У меня vs 22 может быть в ней чтото изменилось. (
@@Бот5329-и5г С 22 студией такая же ошибка , Решение такое private void button1_Click(object sender, EventArgs e) { new Thread(() => //Создаём новый поток { Method(label1); //Говорим что нужно запустить данный метод }) { IsBackground = true, //Указываем выполнять это фоново и должен выполнится до конца Priority = ThreadPriority.Normal //Указываем приороитет }.Start(); //Cтарт потока } void Method(Label label) { if (label1.InvokeRequired) { label1.Invoke(new MethodInvoker(delegate { label.Text = "Допустим лейбл и что?"; })); } label.Text = "Допустим лейбл и что?"; } Происходит потому что вы пытаетесь изменить свойство Text элемента управления label из потока, который не является потоком, в котором был создан этот элемент управления. В Windows Forms все изменения элементов управления должны производиться в потоке пользовательского интерфейса (UI). Чтобы исправить эту проблему, вы должны использовать метод Invoke или BeginInvoke для обновления свойств элементов управления из другого потока.
Thread thread = new Thread(()=> { M(label1); }); Я правильно ли понимаю, что после Thread идут скобки в которых пишется делегат, ссылаясь на метод через лямбда выражение ? И почему в делегате нельзя сделать , например , параметры (s,e) как при событии ?
Спасибо большое что простыми словами объясняешь! Супер! У меня вопрос: как приостановить поток с кнопки и потом опять с кнопки возобновить поток? С этим не могу разобраться...
Отличное объяснение. По делегатам действительно нет ни одного нормального объяснения, только видел пример на коллекции (посчитать к примеру сумму элементов с доп фильтром допустим только четные и т.п.). Эти доп фильтры делать делегатами, и в основном коде вызывать нужный делегат. Но этот пример не живой, ведь вместо всего этого можно использовать лямбда-выражения или вообще LINQ. Другой пример, который встречал - это применение делагатов в обратных вызовах, но там опять же у нас есть события. Т.е. делегаты в чистом виде в нормальном коде не встретишь.
Вы когда-либо с Event-ами работали? Там делегаты очень применимы.
Эдакое сюрное объяснение "с потолка", но когда случится что-то такое делать, оно само по идее в голову придёт, что нужен такой механизм. Так вот пример:
Я -- создатель некоторого события "раздача плова в тарелочке с вилочкой" и я раздаю плов, а ко мне приходят люди за пловом в тарелочке и за вилочкой. Эти люди -- делегаты. И вот я раздаю весь такой, а что будет дальше с этим пловом и одноразовой посудой я класть хотел, а люди-то разные: один съест, другой сделает себе из тарелочки воображаемую шапочку, третий обмажется пловом, четвёртый пойдёт мастерить из него взрывчатку... Но твоя (моя т.е.) задача не меняется, я всего лишь раздаю это.
А ещё более просто и реально -- это, собственно, о делегировании обязанностей в реальном мире. Например:
Вы - интернет-магазин. Вы продаёте товары и Вы ведёте доставку курьерами. Вы формируете заказы к отправке, а куча курьеров их доставляют, но Вася на велосипеде, Петя общественным транспортом, Вова на машине, а Дима вообще рулит большой почтовой службой и выполняет авиа-перевозки.
Третий пример: отправка 1 оповещения (новости) в разные соц-сети одной кнопкой. Вы указали, что на событие реагируют только делегаты, принимающие такой-то набор параметров, из которых состоит ваша новость, например (заголовок и содержание) и всё, море обработчиков может обрабатывать эти данные и заниматься их публикацией каждый в своей соц-сети. Издатель же новости в свою очередь лишён головной боли о том как же эту новость опубликовать везде.
Он делегировал эту обязанность другим, и эти другие -- делегаты.
@@absamurai про интернет-магазин прям из языка снял. Вот пример с рынком: тебе нужна малина? Ты идешь на рынок(к примеру) или в любое удобное место где её можно купить. Ты не идешь на огород и не обращаешься к владельцу производства потому что это неудобно. Так вот тетя Зина - это делегат.
Делегаты придумали именно для событийного программирования. Смысл в том что делегат может иметь множество ссылок на разнице методы (техника подписки и отписки на собитие, хотя в обёртке события самый обычный делегат).
Главное что бы сигнатура подходила.
+ Лямбда выражение (тоже делегат предикат). Так то все делегаты уже придуманы свои пишешь если не знаешь системного. Такие как Action, Func, Predicat, и т.д.
Урок хорош!)
@@absamurai Чел с WindowsForms не работал похоже, там все события на делегатах
Мне приходилось использовать делегаты, чтобы обновлять значения в режиме реального времени в таблице datagridview в WinForm. Было клиент-северное приложение, на клиенте был запущен поток, который получал данные от сервера и заносил инфу в таблицу. Код обновления данных в таблице выполнялся внутри делегата, иначе возникла ошибка, точное описание не помню, но че то там с доступом. Ниже приведен упрощенный фрагмент кода, где использовался делегат.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) // получить данные
{
while (client.Connected == true) // пока клиент подключен
{
lock (locker) // для синхронизации потоков
{
// получение и обработка данных
this.Invoke(new MethodInvoker(delegate
{
// обновление данных в таблице
}));
}
};
}
ХрисТ, ты даже не представляешь себе какой ты молодец. Тебя очень приятно слушать и многие вещи становятся понятнее, чем раньше. Знать и донести это две разные вещи и ты владеешь обоими.
обойи вещи
@@gennadysmirnov5362 Что? Обои вещи, Чем? обоими вещами. Учи русский!!!
@@PK-yd4ki обеими
Реально живое, человеческое объяснение. Спасибо автору за адекватный канал.
Спасибо автору за такую подачу материала! Очень круто, что объяснение идёт бегло, понятно и НЕ на задротском языке:)
Про язык действительно ценно. Очень живо слушается.
Да-да-да)))
...Это очень важно: это не важно!!! Но у вас останется...
Тайны делегатов раскрыты. Ох сколько я их гуглил. За Parallel отдельное спасибо, это что-то с чем-то.
Просмотрел все уроки. Всё понятно, кратко и по существу. Большое спасибо. Если есть возможность, сделай урок по проблематике защиты кода от дизасемблеров и вообще насколько вероятно сохранить алгоритм программы в секрете.
Спасибо вам огромное !!! Вот уже миллион англоязычных туториалов посмотрела, но лучше вас еще нигде не объяснили, ни на каком языке !
Учитель года :) Ты очень хорошо объясняешь! Спасибо, добрый человек :)
Вот это объяснил))). Сколько видосов про потоки смотрел, этот прям с первого раза зашел. Прям все по человечески объяснил, на простом языке. Спасибо. С меня лайк и подписка
Какие же прекрасные уроки. Информация очень понятная, а видео очень приятно смотреть. Спасибо
Добрый день уважаемый. Спасибо за общение с Вами.
Хорошо, что я нарвался на тебя почти в самом начале. Спасибо.
по-людски по-кайфу объясняешь, спасибо!
2 год работаю программистом C#, и понимаю что много чего еще не знаю. По опыту скажу, автор, ты просто красавчик, объясняешь как надо
Популярное заблуждение, что надо всё-всё знать. Надо знать достаточно :) НО - далеко не всё!
Второе популярное заблужнение, что чем дольше работаешь - тем профессиональнее становишься.
Можно и 10 лет неправильно машину водить :-)
Для меня самое простое объяснение делегата - ссылка на метод или список ссылок на группу методов. Нужны они для удобства, когда какое-то событие может вызывать различные методы, которые в свою очередь определяются в рантайме, а не на стадии компиляции. В зависимости от каких-то условий или действий пользователя мы можем вызвать тот или иной метод, а так же целый список методов, меняя его при необходимости. Написал все нужные методы, а потом просто тупо добавляешь на них ссылку в делегат или убирай из него. Может плюсы делегатов не особо очевидны, когда метод один и он либо вызывается событием, либо нет и третьего не дано. Но когда присутствует большая вариативность поведения, то делегаты могут очень помочь.
Да, абсолютно верно, наконец-то я тоже до этого допёр!) В данном видео не показана одна важная функция делегатов - это расширения списка методов делегата через простую операцию «+=». Это супер удобно при работе в рантайме
Уроки бомбезные,и как только ты все это запоминаешь,мне бы твоё мастерство.Браво👍👍
Самое понятное объяснение. Еще бы окошко студии немножко увеличить чтобы не приглядываться... На экране еще много свободного места)
Вот по таким видео можно даже научится кодить. И смотреть интересно, и много полезной информации.
Очень понятно объясняешь. Про if и else было все очень понятно. Спасибо!
Обычно, подобные уроки ставлю на скорость воспроизведения х1.5 или х2. Тут я впервые захотел чуть понизить скорость подачи :)
А в целом круто, четкий грамотно сформулированный поток инфы.
Думаю это максимум, что можно уложить в 30 минут, так что за более подробным и вдумчивым перевариванием нужно идти читать документацию.
Спасибо за труд!
К делегатам добавлю некоторое пояснение. Да делегат в простом варианте является конвертером члена класса "метод" в объект, что-бы с методом можно было обращаться как с любым другим объектом (перемеренные, поля, свойства, параметры и тд.). Делегаты из таких структур появились достаточно рано и стали базисом для последующего синтаксического сахара такие как анонимные методы (как мы собираемся обращаться к анонимному методу если у него нету имени), лямбда-выражения (немного функционального программирования из F# и Омега# в C# которые просто красиво написанные анонимные методы) и типы делегаты Action(0...P16) и Func(return,0...P16) (очень сильно упрощают жизнь если нужны всевозможные колбеэки и актуаторы и последнее это события (события и есть делегат только более красиво написанный, события можно и на чистых делегатах написать, толком разницы нету кроме красивости кода). А живой пример смотри на само слово делегат что в переводе на русский является представитель по типу торговых представителей (орифлеймы всякие), послы в посольствах государственных по нормальному это государственные представители и так далее. Если что-то как-то надо представлять каким либо образом это вот делегат. А так это выросло из шаблона проектирования который так и называется делегат (иногда как шаблон делегирования)
Спасибо большое!
Но я хотел услышать про ТреэдПул)))
Это просто восхитительно !!! Можно мне такого препода ? А ? Сколько каналов перелопатил, никто так понятно и находчиво не объясняет, просто вау !
Очень полезное видео - грамотно и доступным языком.
По моему, необходимость делегатов хорошо объясняет паттерн "Стратегия". Пример такой: У тебя есть определённая стратегия работы. Например: строительство коттеджного посёлка. И у тебя есть проекты строительства домов, дома все похожие, отличаются только в мелочах. Одна из задач в каждом проекте - выкопать котлован под фундамент. Так вот, в каких-то случаях ты можешь загнать туда чернорабочих, и они выкопают (т.к. например, экскаватор туда не проедет). В другом случае на эту же задачу ты отправишь мини-экскаватор. В третьем случае ты отправишь мощный экскаватор с отбойником, (т.к. там к примеру, там находится особо крепкий грунт). Так и в программировании - у нас есть общий метод, с командами - выкопать фундамент, подготовить основание, сделать опалубку, залить фундамент и т.д. а какими методами ты будешь строить каждый конкретный дом - зависит от конкретной ситуации, которая задаётся в конкретном случае и с конкретными условиями.
Аналогии автора просто 10 из 10.
Большое спасибо за Ваш труд. Привет из Болгарии ... 🙂
Очень грамотный подход! Очень доволен что нашел ваш канал! Подписка
Спасибо за видос. Теперь многое стало чуть яснее.
Огромное спасибо! Очень понятно. Сразу понял как лучше сделать
Я постоянно не мог найти инфу по этому всему, пытался нарыть инфу из самых странных источников, но тут нашел это видео, и просто любовь с первого взгляда
Делегат - можно понимать как callback функцию. Строготипизированный колбек дает большую гибкость. Во в первых - он гарантирует, что переданная лямбда соответствует сигнатуре, во вторых - внутри своего метода он позволяет на основании своей сигнатуры писать корректный в плане типов код, что помогает не заниматься отладкой 8 часов, в третьих - не обязательно в метод передавать лямбду, хоть иногда это, безусловно, удобно. list.Sort((a, b) => a.Id.CompareTo(b.Id)) например можно заменить на list.Sort(Sort.ById).
Делегаты очень широко используются в мире функционального программирования, да и в классическом ООП (например, паттерн шаблонный метод)
У меня есть бутылка и она закрытая. "Открытие крышки" - вот наш делегат!. Мы можем открыть эту бутылку нормальным способом, а можно - ложкой; можно зубами тоже (если они здоровые), некоторые могут и глазом.
Очень круто, спасибо большое за эти уроки. Все очень доступно и понятно, что огромная редкость.
Про делегаты. Предположим есть комната в которой нет ни окон ни дверей, задача в ней убраться: пропылесосить, протереть пыль. Для решения нужен тот кто уберет комнату и способ в эту комнату попасть. Представим что у нас есть Маша, Петя и Вася - все они могут убрать комнату. Теперь надо их в комнату как-то поместить, есть два варианта: 1) для каждого из них прорубить отдельный вход; 2) сделать ДВЕРЬ.
Предположим, что Маша, Петя и Вася хотят покушать. Есть вариант каждому кушать из своей тарелки, а можно кушать просто с КАСТРЮЛИ.
Нет, не годится. Жду новых примеров. Кстати, после выхода этого видео, спустя какое-то время нашёл применение делегату - доступ к контролу из класса.
Это боль...
@@XpucT Вопрос изначально был зачем? Ну он же вроде как для соплей) Ну типа есть 15 алгоритмов сортировки массива и какой-нибудь PrintTime() для подсчета времени работы каждого алгоритма. Мы делаем PrintTime(Action ... ) и норм, нет? Подобие функциональной обертки из плюсов.
Спасибо огромное за видео, очень помогло.
Большое спасибо, за Ваш труд. У Вас очень хорошо получается!
Красавчик! Все понятно
Отличное объяснение! Благодаря тебе у меня единственного в группе курсовая работа будет с потоками))
По делегатам, строим аналогию с C++. Функцию нельзя напрямую передать в функцию в качестве параметра. Но можно передать указатель (адрес, "делегат") / Даже в C++ не рекомендуют, в настоящее время, использовать указатели на функцию, а использовать класс Functional - аналог лямбда выражений в C#.
Спасибо, посмотрела сначала про async await, где все доступным языком разложено по полочкам
Спасибо за урок, единственный урок после которого я понял как использовать Thread
как хорошо что ты на эту тему видео записал
Отлично объяснил. Спасибо.
Спасибо, перевел свой софт для сжатия игр во много поток, ускорил работу в 2-5 раз)
Я еще использовал сплит списка строк, на мини списки по 3 элемента, чтобы обработка шла, в каждом потоке по 3 элемента, вместо всех элементов в одном потоке) Мозг лопнул, но по кайфу работает
Про делегаты приведу пример. Есть метод который вызывается для заполнения progressBar, и вот у нас где-то там в другом классе, в другом пространстве имен есть метод который считывает огромный файл, и для этого мы создадим делегат и передадим как параметр, чтоб увидеть прогресс выполнения/чтения файла. Для событий без делегатов не обойтись
Очень хорошее видео, спасибо !
Ты когда нибудь отдыхаешь? Спасибо тебе!
Ааааааа, ты лучший!!!!! Спасибо большое за видео)
Круто!!! Понятно, и без соплежуйства, спасибо!
Потрясающе!
20:42 "New Thread, Старт! *Погнал*"
Чет ору с этого, ахахахахахахахахахахахахахаха. Забавно вы это говорите и когда представляешь тоже ситуация забавная! (типа слишком быстро)
Рождается и ему сразу старт, и он погнал
Это было сильно! Спасибо!
Спасибо за урок, покажи плиз как работать с EF 6(связи, работа с данными и т.п.)
Использовал делегат чтобы на одну кнопку вешать 2 метода(старт/стоп), т.е. кнопка вызывает делегат ,а дальше в методе к ему привязывается другой метод и второй клик по кнопке уже для совсем других действий. Может можно было реализовать проще, но это первое что в голову пришло)
Наконец то!!! Наконец-то я поняла эти ***чие делегаты!!!!!!
это просто лучшее объяснение !!!!!!!!!!!)))))
я тебя обожаю, умоляю делай еще видео
Спасибо за видео! Отлично всё разъяснено в ролике.
Планируете ли снимать ролики по алгоритмам, паттернам? Было бы здорово коснуться темы DI, IoC -контейнеров.
Да, после ещё несколько тем в Windows Forms приступим к WPF сразу же на MVVM.
Большое Спасибо.
Как-то сжато, немного рвано, дёргано, но при этом класно получается ))
По поводу делегатов и директора как раз все понятно. Ты обращаешься именно не к человеку, а к тому, кто выполняет обязанности директора. Если директор в отпуске, за него ответит зам или секретарь, или хз кто. Тебе не важно, кто именно, какой именно человек, главное, чтобы он был уполномечен. А лямбда оператор - это всего лишь синтаксический сахар.
очень круто, многое понял! Осталось понять как сделать поток который бы выполнял задачи по записи и чтению файлов и передавал их в основной поток (привет из Unity и Monobehavior работающих в основном потоке)
Мне понравилось объяснение про ружье и звонок)) А я когда проходил делегаты думал что если я не понимаю его применения на практике, то я че-то не так понял и вообще тупой)
Круто! Пошел переписывать свой проект ))
Очень доходчиво объясняешь, скобки правильно расставляешь, так лучше, чем в строку.
Юмора как раз столько, сколько надо)
Если возможно - уменьши область захвата видео до размера окна виртуалки, т.к. мелкие символы на 720P не видно нормально (Инет 3G, живу вдали от цивилизации)
Спасибо, огромное. Такую сложную тему объяснить настолько доступно. Наконец я чувствую,что смогу пользоваться этими инструментами нормально.
Присоединяюсь ко всем словам благодарности. Спасибо за проделанную работу!
Хочу дать обратную связь. (13:09) В строчку или в столбик записан код на экране не очень принципиально. Есть только одно пожелание. Увеличьте, пожалуйста, размер шрифта кода. Если смотреть с телефона, то почти ничего не видно. Спасибо!)
PS. На 150% увеличении комфортно (15:35) 🙂
Уроки просто топ. Спасибо
Давно видео не выходило, надеюсь у вас всё хорошо.
Был бы рад увидеть уроки по EF (core), либо что-нибудь другое связанное с бд.
Спасибо!
Очень занят пока. Будут новые видео ;) Много.
спустя 5 лет опять смотрю это видео. Столько событий произошло, а я заново пытаюсь вкатиться. Сейчас хотя бы работу нашел, но опять наткнулся на делегаты.
Хорошее объяснение. Лайк с меня
О, христ, я не знал, что ты пилишь уроки). Давно откладывал многопоточку, после шилда так и не вернулся к ней, думаю это жирный намек)
Делегат это шаблон обертки для методов определенной сигнатуры указанной в определении делегата. После создания экземпляров делегатов в них можно помещать методы соответствующей сигнатуры. Также экземляры делегатов можно складывать и вычитать, при этом будут добавляться и удаляться методы внутри них. Зачем это надо? Ну, например для событий. Событие это по сути и есть делегат, обернутый в виде свойства. Можно добавлять в него ссылки на методы(подписываться) и удалять(отписываться). Компилятор создает делегаты неявно когда вы передаете лямбду в метод или подписываете метод на событие. Все делегаты имеют метод Invoke() который их вызывает. По сути делегаты это удобный метод хранения ссылок на методы и работы с ними. Грубо говоря как Object для переменных, только делегаты для методов.
Вот спасибо, отлично объяснил.
Скажите, для парсинга сайтов (получение страниц и извлечения из них данных) лучше использовать многопоточность или async?
async сегодня в любом вопросе предпочтительнее.
@@XpucT Спасибо!
Когда следующий урок? Жду с нетерпением !!!
Будут ;)
спасибо , Дядь.
Спасибо тебе. Сделай пожалуйста шрифт по больше. На телефоне сложно смотреть.
Спасибо огромное за урок, очень классное объяснение. Насчёт написания кода, как по мне, то в строчку лучше, и понятнее. Ещё вопрос, есть ли урок работе с процессами, и сетевое программирование ?
Будет позже 🤝
Живой пример использования делегатов. Вам нужно решить систему из 100 дифференциальных уравнений вида dy/dx =F(x, y1....y100). Правые части системы - функции F записываются как массив делегатов одинаковой сигнатуры. Но начинка внутри каждой функции - разная. Программа видит делегат и вызывает функцию нужного содержания с заданным набором аргументов. Это как указатель на функцию в С.
Советую очень серьезно относится к этому уроку, так как сложно без делегатов и без асинхронной/многопоточной программировании
делегат удобен тогда, когда тебе нужен список делегатов (то-есть у тебя есть методы 1,2,3,4,5,6,7) и ты хочешь их выполнять, у тебя есть список с этими методами типа хочу чтобы, выполнялись так 1,2,3,2,2,2,2,2,1,3,4,5 и ну это можно когда количество небольшое прописать вручную, а так существуют делегаты которые можно добавить в список и выполнять когда тебе нужно и в любой последовательности (станки чпу, сценарии какие-то)
Спасибо за видео друг ! и Коту привет ! Вопрос . Запустить поток можно так: поток.Start(); а есть ли возможность остановить выполнение потока когда мне нужно ? или как "убить" поток в процессе работы программы ? Спасибо !
поток.Suspend(); - останавливает поток.
Всё остальное гуглттьс по "C# работа с потоками".
Ты мне мозг сломал, благо что рядом стояла бутылка водки. Пойду трезветь )))
По поводу делегатов, в основном используется другая их форма - события. Ну то есть события и есть делегаты, только более продвинутые. Ну уж я надеюсь, что никто не отрицает полезность событий)
Классное видео, на тему потоков) Не могли бы снять как одновременно в потоках выполнять одну задачу?
Из того что знаю я deligate нужен как атрибут метода.
Такой метод не имеет тела и нужен он чтобы запомнить сигнатуру.
Например () когда есть коллекция свойств с разными атрибутами и у нас есть метод который возвращает все свойства с одним атрибутом, все свойства с другим и так далее...В этому случае можно написать метод обертку в который передается параметром коллекция и делигативный метод, который проверяет свойство на причастность к атрибуту. И тогда у нас будет не N методов по все атрибутам, а только 2 : один делигат и метод этот делигат использующий.
Конкретно в тредах делигат видимо используется для того чтобы передать сигнатуру метода.
Спасибо большое ❤
Делегаты нужны для того, чтобы различные функции в качестве аргументов передавать в другие функции, чтобы потом эти переданные в качестве аргументов функции вызывались когда угодно, идеальный пример - конвейер компонентов Middleware для Asp.Net Core. Если ошибаюсь, поправьте
По поводу примера из жизни про делегаты. Жили-были крестьяне, которых царское самодержавие сильно угнетало. И тут приходит Ленин со своей советской властью. Крестьяне обрадовались, что сейчас им Ленин этой самой земли-то и прибавит. Вот только как об этом сказать Ленину?
Есть вариант: каждый из крестьян идёт к Ленину и говорит: "Владимир Ильич, я крестьянин Иванов (Петров, Сидоров), мне бы земли побольше". Потом они почесали репу и решили, что так не пойдёт. Это получается, что вся деревня отправится в Петроград. Тут и красноармейцы по дороге могут остановить и расстрелять (ибо любая власть боится толпы народа), да и работать на земле кому-то нужно.
Вот крестьяне и решили отправить Ленину одного Пахома. Так и говорят: "Ты, Пахом, будешь нашим делегатом. Как Ленин тебя спросит, мол, зачем пришёл, ты изложишь ему нашу задачу". Тут Иванов кричит: "и про меня не забудь". И Петров ему вторит: "и про меня тоже". Так все крестьяне дружно подписались на делегат. Чтобы как Ленин подписал свой указ, так чтобы он на всех распространился, кто к нему Пахома отправил.
Неплохо =)
С await не понял, как работать.
Есть код. К примеру, хочу чтобы что-то при нажатии на button выполнялось асинхронно. И хочу чтобы там же менялся текст в label1.
async private void button1_Click(object sender, EventArgs e)
{
await Task.Run(() => {
// какой-то код
// обработка потока при Debug
BeginInvoke((MethodInvoker)(() =>
{
label1.Text = $"Число {result} является Doubleton";
label2.Text = "Результат готов";
}));
});
}
Но при таком коде ошибки в Debug нет, но зато вся асинхронность просто улетучивается. Более того асинхронность перестает работать даже в релизе без отладки.
Пробовал и с action и с просто Invoke, что я делаю не так? :) И спасибо за видео !!!
Invoke((Action)(() => код
BeginInvoke не нужен тут.
спасибо большое!!!
Нихрена не понял, но то что мне надо было я сделал xD спасибо )
Спасибо! выручил! пиши пожалуйста в столбец -проще понимать.... ну по крайне мере мне)))
Допустим у нас имеется прибор, подключеный к ПК через COM порт (USB). И необходимо через протокол (не важно какой) отправлять на него данные, а также обрабатывать его ответы. С визуальной составляющей, используя Forms, проблем возникнуть не дожно. Вопрос состоит вот в чем: можно ли при помощи C# и Visual Studio Community создать программу, которая будет контролировать входные и управлять выходными данными (последовательности байтов согласно выбраному протоколу) COM порта, к которому подключен прибор ?
Не думаю, что возникнут какие-то проблемы. Язык как раз на это и рассчитан. На любые сложности.
Делегат это ссылка на метод (функцию, порядок неопределённых действий) который будет использован в классе или методе.
Когда это может быть полезно?
Когда хочешь сделать код универсальным без модификаций имплементации основного класса и в тоже время сделать код более компактным.
LINQ прекрасный образчик универсальности.
Например: вы вычисляете остаток по кредиту за период.
вы можете всё сделать просто: в одном методе.
а можете в определенный момент(как параметр метода или как атрибут класса) передать функцию по вычислению процента по кредиту какому-то пользователю класса. При этом вам не надо наследовать класс (в C# можно наследовать только от одного класса). Вы даже можете сделать ваш класс закрытым для модификации.
По моему скромному мнению: В каком-то смысле делегаты(ссылка на метод) противопоставляет себя одному из принципов ООП: инкапсуляции.
красавчик
Обожаю c#, пользуюсь 2008 студией, потому что не люблю выкачивать тонны гигабайт и люблю легкие ide, уже тогда было столько фичей в нем. Тогда наверное он казался языком из будущего.
А вот у вас на 14:26 в режиме Release меняется lable а у меня почемуто не меняется и выдает ошибку.
System.InvalidOperationException: "Недопустимая операция в нескольких потоках: попытка доступа к элементу управления 'label1' не из того потока, в котором он был создан."
Тоже запускаю в Release. С чем это может быть связано?
Решение ➜ Очистить решение.
Либо перезапустить проект. Но в Release такого не должно быть.
Если ошибка повторяется, начните сначала или создайте чистый проект. Где-то тогда Ваш косяк.
@@XpucT Спасибо за ответ. Извините что заставил обратить на себя внимание. В новом проекте такая же борода. Очистить решение не помогло.
У меня vs 22 может быть в ней чтото изменилось. (
@@Бот5329-и5г рекомендую 2019.
@@Бот5329-и5г
С 22 студией такая же ошибка ,
Решение такое
private void button1_Click(object sender, EventArgs e)
{
new Thread(() => //Создаём новый поток
{
Method(label1); //Говорим что нужно запустить данный метод
})
{
IsBackground = true, //Указываем выполнять это фоново и должен выполнится до конца
Priority = ThreadPriority.Normal //Указываем приороитет
}.Start(); //Cтарт потока
}
void Method(Label label)
{
if (label1.InvokeRequired)
{
label1.Invoke(new MethodInvoker(delegate
{
label.Text = "Допустим лейбл и что?";
}));
}
label.Text = "Допустим лейбл и что?";
}
Происходит потому что вы пытаетесь изменить свойство Text элемента управления label из потока, который не является потоком, в котором был создан этот элемент управления. В Windows Forms все изменения элементов управления должны производиться в потоке пользовательского интерфейса (UI).
Чтобы исправить эту проблему, вы должны использовать метод Invoke или BeginInvoke для обновления свойств элементов управления из другого потока.
Автор рассказывает об этом после 14.26
Thread thread = new Thread(()=>
{
M(label1);
});
Я правильно ли понимаю, что после Thread идут скобки в которых пишется делегат, ссылаясь на метод через лямбда выражение ? И почему в делегате нельзя сделать , например , параметры (s,e) как при событии ?
Сейчас актуальнее делать ➜ await Task.Run(() => {});
@@XpucT понял
Спасибо большое что простыми словами объясняешь! Супер! У меня вопрос: как приостановить поток с кнопки и потом опять с кнопки возобновить поток? С этим не могу разобраться...
ua-cam.com/video/DQTmo-xGgZk/v-deo.html
@@XpucT спасибо огромное! Я сделала через if и все получилось! 😀