Уроки C# - Потоки, Thread, Invoke, Action, delegate, Parallel.Invoke - C#

Поделиться
HTML-код
  • Опубликовано: 2 окт 2024
  • Донаты и на кофе ➜ t.me/win10twea...
    Эксклюзив для спонсоров ➜ / xpuct
    Если недоступна спонсорка ➜
    В этом видео Вы узнаете всё о потоках, а также, как решить проблему:
    Недопустимая операция в нескольких потоках: попытка доступа к элементу управления не из того потока, в котором он был создан (The calling thread cannot access this object because a different thread owns it).
    Форум по C#:
    win10tweaker.r...
    #Потоки #Thread #Многопоточность #Invoke #Action #delegate #Parallel.Invoke #СиSharp #СиШарп

Комментарии • 392

  • @chokayes7830
    @chokayes7830 5 лет назад +42

    Отличное объяснение. По делегатам действительно нет ни одного нормального объяснения, только видел пример на коллекции (посчитать к примеру сумму элементов с доп фильтром допустим только четные и т.п.). Эти доп фильтры делать делегатами, и в основном коде вызывать нужный делегат. Но этот пример не живой, ведь вместо всего этого можно использовать лямбда-выражения или вообще LINQ. Другой пример, который встречал - это применение делагатов в обратных вызовах, но там опять же у нас есть события. Т.е. делегаты в чистом виде в нормальном коде не встретишь.

    • @absamurai
      @absamurai 4 года назад +14

      Вы когда-либо с Event-ами работали? Там делегаты очень применимы.
      Эдакое сюрное объяснение "с потолка", но когда случится что-то такое делать, оно само по идее в голову придёт, что нужен такой механизм. Так вот пример:
      Я -- создатель некоторого события "раздача плова в тарелочке с вилочкой" и я раздаю плов, а ко мне приходят люди за пловом в тарелочке и за вилочкой. Эти люди -- делегаты. И вот я раздаю весь такой, а что будет дальше с этим пловом и одноразовой посудой я класть хотел, а люди-то разные: один съест, другой сделает себе из тарелочки воображаемую шапочку, третий обмажется пловом, четвёртый пойдёт мастерить из него взрывчатку... Но твоя (моя т.е.) задача не меняется, я всего лишь раздаю это.
      А ещё более просто и реально -- это, собственно, о делегировании обязанностей в реальном мире. Например:
      Вы - интернет-магазин. Вы продаёте товары и Вы ведёте доставку курьерами. Вы формируете заказы к отправке, а куча курьеров их доставляют, но Вася на велосипеде, Петя общественным транспортом, Вова на машине, а Дима вообще рулит большой почтовой службой и выполняет авиа-перевозки.
      Третий пример: отправка 1 оповещения (новости) в разные соц-сети одной кнопкой. Вы указали, что на событие реагируют только делегаты, принимающие такой-то набор параметров, из которых состоит ваша новость, например (заголовок и содержание) и всё, море обработчиков может обрабатывать эти данные и заниматься их публикацией каждый в своей соц-сети. Издатель же новости в свою очередь лишён головной боли о том как же эту новость опубликовать везде.
      Он делегировал эту обязанность другим, и эти другие -- делегаты.

    • @bylabunskyy2227
      @bylabunskyy2227 4 года назад +1

      @@absamurai про интернет-магазин прям из языка снял. Вот пример с рынком: тебе нужна малина? Ты идешь на рынок(к примеру) или в любое удобное место где её можно купить. Ты не идешь на огород и не обращаешься к владельцу производства потому что это неудобно. Так вот тетя Зина - это делегат.

    • @pasha5760
      @pasha5760 4 года назад +2

      Делегаты придумали именно для событийного программирования. Смысл в том что делегат может иметь множество ссылок на разнице методы (техника подписки и отписки на собитие, хотя в обёртке события самый обычный делегат).
      Главное что бы сигнатура подходила.
      + Лямбда выражение (тоже делегат предикат). Так то все делегаты уже придуманы свои пишешь если не знаешь системного. Такие как Action, Func, Predicat, и т.д.
      Урок хорош!)

    • @indawl
      @indawl 4 года назад +5

      @@absamurai Чел с WindowsForms не работал похоже, там все события на делегатах

    • @Usermage_
      @Usermage_ 4 года назад +1

      Мне приходилось использовать делегаты, чтобы обновлять значения в режиме реального времени в таблице datagridview в WinForm. Было клиент-северное приложение, на клиенте был запущен поток, который получал данные от сервера и заносил инфу в таблицу. Код обновления данных в таблице выполнялся внутри делегата, иначе возникла ошибка, точное описание не помню, но че то там с доступом. Ниже приведен упрощенный фрагмент кода, где использовался делегат.
      private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) // получить данные
      {
      while (client.Connected == true) // пока клиент подключен
      {
      lock (locker) // для синхронизации потоков
      {
      // получение и обработка данных
      this.Invoke(new MethodInvoker(delegate
      {
      // обновление данных в таблице
      }));
      }
      };
      }

  • @lega3893
    @lega3893 5 лет назад +6

    Вот это объяснил))). Сколько видосов про потоки смотрел, этот прям с первого раза зашел. Прям все по человечески объяснил, на простом языке. Спасибо. С меня лайк и подписка

  • @Nick-wz6tz
    @Nick-wz6tz 4 года назад +4

    Спасибо вам огромное !!! Вот уже миллион англоязычных туториалов посмотрела, но лучше вас еще нигде не объяснили, ни на каком языке !

  • @NoName-tk4ym
    @NoName-tk4ym Год назад +2

    Учитель года :) Ты очень хорошо объясняешь! Спасибо, добрый человек :)

  • @vitalyryabchich257
    @vitalyryabchich257 3 года назад +5

    Я постоянно не мог найти инфу по этому всему, пытался нарыть инфу из самых странных источников, но тут нашел это видео, и просто любовь с первого взгляда

  • @ozarmehrodilov9698
    @ozarmehrodilov9698 5 лет назад +4

    Про делегаты приведу пример. Есть метод который вызывается для заполнения progressBar, и вот у нас где-то там в другом классе, в другом пространстве имен есть метод который считывает огромный файл, и для этого мы создадим делегат и передадим как параметр, чтоб увидеть прогресс выполнения/чтения файла. Для событий без делегатов не обойтись

  • @potuStoronka
    @potuStoronka 5 лет назад +2

    Спасибо, посмотрела сначала про async await, где все доступным языком разложено по полочкам

  • @ИльяВладимиров-у2б
    @ИльяВладимиров-у2б 3 года назад +1

    Очень грамотный подход! Очень доволен что нашел ваш канал! Подписка

  • @Pavluha161
    @Pavluha161 5 лет назад +26

    Ты когда нибудь отдыхаешь? Спасибо тебе!

  • @sergezaybo6572
    @sergezaybo6572 4 года назад +24

    Просмотрел все уроки. Всё понятно, кратко и по существу. Большое спасибо. Если есть возможность, сделай урок по проблематике защиты кода от дизасемблеров и вообще насколько вероятно сохранить алгоритм программы в секрете.

  • @Сергей-у3к8й
    @Сергей-у3к8й 5 лет назад +1

    Про делегаты. Предположим есть комната в которой нет ни окон ни дверей, задача в ней убраться: пропылесосить, протереть пыль. Для решения нужен тот кто уберет комнату и способ в эту комнату попасть. Представим что у нас есть Маша, Петя и Вася - все они могут убрать комнату. Теперь надо их в комнату как-то поместить, есть два варианта: 1) для каждого из них прорубить отдельный вход; 2) сделать ДВЕРЬ.

    • @XpucT
      @XpucT  5 лет назад +1

      Предположим, что Маша, Петя и Вася хотят покушать. Есть вариант каждому кушать из своей тарелки, а можно кушать просто с КАСТРЮЛИ.
      Нет, не годится. Жду новых примеров. Кстати, после выхода этого видео, спустя какое-то время нашёл применение делегату - доступ к контролу из класса.
      Это боль...

    • @Сергей-у3к8й
      @Сергей-у3к8й 5 лет назад +1

      @@XpucT Вопрос изначально был зачем? Ну он же вроде как для соплей) Ну типа есть 15 алгоритмов сортировки массива и какой-нибудь PrintTime() для подсчета времени работы каждого алгоритма. Мы делаем PrintTime(Action ... ) и норм, нет? Подобие функциональной обертки из плюсов.

  • @woodlandfantomas2044
    @woodlandfantomas2044 Год назад +2

    По делегатам, строим аналогию с C++. Функцию нельзя напрямую передать в функцию в качестве параметра. Но можно передать указатель (адрес, "делегат") / Даже в C++ не рекомендуют, в настоящее время, использовать указатели на функцию, а использовать класс Functional - аналог лямбда выражений в C#.

  • @ivan140600
    @ivan140600 5 лет назад +29

    Спасибо автору за такую подачу материала! Очень круто, что объяснение идёт бегло, понятно и НЕ на задротском языке:)

    • @lizastepantsova5230
      @lizastepantsova5230 3 года назад

      Про язык действительно ценно. Очень живо слушается.

    • @vladoss4643
      @vladoss4643 Год назад

      Да-да-да)))
      ...Это очень важно: это не важно!!! Но у вас останется...

  • @Jenyaza01
    @Jenyaza01 5 лет назад +3

    Как-то сжато, немного рвано, дёргано, но при этом класно получается ))

  • @adamiyy
    @adamiyy 5 лет назад +15

    Тайны делегатов раскрыты. Ох сколько я их гуглил. За Parallel отдельное спасибо, это что-то с чем-то.

  • @MrOlezhandr
    @MrOlezhandr 4 года назад +3

    Очень доходчиво объясняешь, скобки правильно расставляешь, так лучше, чем в строку.
    Юмора как раз столько, сколько надо)
    Если возможно - уменьши область захвата видео до размера окна виртуалки, т.к. мелкие символы на 720P не видно нормально (Инет 3G, живу вдали от цивилизации)

  • @pavelpuchkov7422
    @pavelpuchkov7422 4 года назад +1

    Присоединяюсь ко всем словам благодарности. Спасибо за проделанную работу!
    Хочу дать обратную связь. (13:09) В строчку или в столбик записан код на экране не очень принципиально. Есть только одно пожелание. Увеличьте, пожалуйста, размер шрифта кода. Если смотреть с телефона, то почти ничего не видно. Спасибо!)
    PS. На 150% увеличении комфортно (15:35) 🙂

  • @alexandrsazanov9402
    @alexandrsazanov9402 3 года назад +4

    Делегат это грубоговоря ссылка на метод. Все событийная модель на нем построена.

  • @JenyaHW
    @JenyaHW 4 года назад +1

    делегат удобен тогда, когда тебе нужен список делегатов (то-есть у тебя есть методы 1,2,3,4,5,6,7) и ты хочешь их выполнять, у тебя есть список с этими методами типа хочу чтобы, выполнялись так 1,2,3,2,2,2,2,2,1,3,4,5 и ну это можно когда количество небольшое прописать вручную, а так существуют делегаты которые можно добавить в список и выполнять когда тебе нужно и в любой последовательности (станки чпу, сценарии какие-то)

  • @malygos1898
    @malygos1898 4 года назад +13

    Реально живое, человеческое объяснение. Спасибо автору за адекватный канал.

  • @ozarmehrodilov9698
    @ozarmehrodilov9698 5 лет назад +2

    Советую очень серьезно относится к этому уроку, так как сложно без делегатов и без асинхронной/многопоточной программировании

  • @YarikMud
    @YarikMud 5 лет назад +15

    Спасибо за урок, покажи плиз как работать с EF 6(связи, работа с данными и т.п.)

  • @phat80
    @phat80 3 года назад +9

    Для меня самое простое объяснение делегата - ссылка на метод или список ссылок на группу методов. Нужны они для удобства, когда какое-то событие может вызывать различные методы, которые в свою очередь определяются в рантайме, а не на стадии компиляции. В зависимости от каких-то условий или действий пользователя мы можем вызвать тот или иной метод, а так же целый список методов, меняя его при необходимости. Написал все нужные методы, а потом просто тупо добавляешь на них ссылку в делегат или убирай из него. Может плюсы делегатов не особо очевидны, когда метод один и он либо вызывается событием, либо нет и третьего не дано. Но когда присутствует большая вариативность поведения, то делегаты могут очень помочь.

    • @benjaminBTN
      @benjaminBTN Год назад

      Да, абсолютно верно, наконец-то я тоже до этого допёр!) В данном видео не показана одна важная функция делегатов - это расширения списка методов делегата через простую операцию «+=». Это супер удобно при работе в рантайме

  • @Бот5329-и5г
    @Бот5329-и5г 2 года назад +1

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

  • @mishabadichel1618
    @mishabadichel1618 4 года назад +1

    Уроки просто топ. Спасибо

  • @DeXMask
    @DeXMask 4 года назад +2

    Спасибо! выручил! пиши пожалуйста в столбец -проще понимать.... ну по крайне мере мне)))

  • @dgulakov
    @dgulakov 4 года назад +1

    Делегат это описание метода - типы входных параметров, тип результата, именно описание а не сигнатура. Отличие описания от сигнатуры - последняя включает имя метода и используется вообще для других целей. Экземпляр делегата это ссылка на метод соответствующий описанию. Реализация?)) События, колбэки и так далее. Я понимаю почему вы конструкции типа delegate(int arg) { return arg; } называете делегатами, вот только это не делегаты и даже не их экземпляры, это анонимные функции/методы, которые потом разбираются компилятором в делегат, сам метод и экземпляр делегата. В первом приближении лямбда выражения это синтаксический сахар анонимных функций, но это не так и у них есть отличия, например анонимные функции могут пропускать объявление аргументов, т.е. Action f = delegate { Console.Write("Hello"); }; f("world"); работает, а лямбда выражения нет, в то же время лямбда могут приводиться как к делегату, так и к дереву выражений, а анонимные функции только к делегату.

  • @yz777zhumabayev6
    @yz777zhumabayev6 2 года назад +2

    Спасибо большое!
    Но я хотел услышать про ТреэдПул)))

  • @olegalekseev325
    @olegalekseev325 5 лет назад +7

    Спасибо тебе. Сделай пожалуйста шрифт по больше. На телефоне сложно смотреть.

  • @mqst
    @mqst 2 года назад +2

    20:42 "New Thread, Старт! *Погнал*"
    Чет ору с этого, ахахахахахахахахахахахахахаха. Забавно вы это говорите и когда представляешь тоже ситуация забавная! (типа слишком быстро)
    Рождается и ему сразу старт, и он погнал

  • @benjaminBTN
    @benjaminBTN Год назад +1

    Отдельная багодарочка за нормально произношение Thread, а не вот эти вот все Сссрэды...)

  • @alexandrsharp920
    @alexandrsharp920 4 года назад +2

    Thread уже считается legacy code.... нужно использовать Task

    • @XpucT
      @XpucT  4 года назад

      Всё правильно 👍

  • @belov_dev
    @belov_dev 3 года назад +5

    Это просто восхитительно !!! Можно мне такого препода ? А ? Сколько каналов перелопатил, никто так понятно и находчиво не объясняет, просто вау !

  • @AnkeKatome
    @AnkeKatome 2 года назад +3

    К делегатам добавлю некоторое пояснение. Да делегат в простом варианте является конвертером члена класса "метод" в объект, что-бы с методом можно было обращаться как с любым другим объектом (перемеренные, поля, свойства, параметры и тд.). Делегаты из таких структур появились достаточно рано и стали базисом для последующего синтаксического сахара такие как анонимные методы (как мы собираемся обращаться к анонимному методу если у него нету имени), лямбда-выражения (немного функционального программирования из F# и Омега# в C# которые просто красиво написанные анонимные методы) и типы делегаты Action(0...P16) и Func(return,0...P16) (очень сильно упрощают жизнь если нужны всевозможные колбеэки и актуаторы и последнее это события (события и есть делегат только более красиво написанный, события можно и на чистых делегатах написать, толком разницы нету кроме красивости кода). А живой пример смотри на само слово делегат что в переводе на русский является представитель по типу торговых представителей (орифлеймы всякие), послы в посольствах государственных по нормальному это государственные представители и так далее. Если что-то как-то надо представлять каким либо образом это вот делегат. А так это выросло из шаблона проектирования который так и называется делегат (иногда как шаблон делегирования)

  • @ppivperm
    @ppivperm 4 года назад +4

    В столбец - лучше для понимания. Мы же - изучающие. В строку конечно красивее, но и менее понятно.

  • @Abo56Volo
    @Abo56Volo 4 года назад +1

    У меня есть бутылка и она закрытая. "Открытие крышки" - вот наш делегат!. Мы можем открыть эту бутылку нормальным способом, а можно - ложкой; можно зубами тоже (если они здоровые), некоторые могут и глазом.

  • @notn9380
    @notn9380 5 лет назад +6

    Хорошо, что я нарвался на тебя почти в самом начале. Спасибо.

  • @delusio5638
    @delusio5638 Год назад +1

    ваще в мелкософте работают извращенцы и они любят придумывать обычным вещам необычные названия)))
    delegate это просто адрес конкретного метода ну или объекта, а фишка наверно в том что слово *_delegate_* это красиво заумно и непонятно а кто понял могут делать умный и загадочный вид))))))))))))))))))))))))

  • @zhivoder915
    @zhivoder915 2 месяца назад +1

    Все хорошо, грамотно, свежо, но блин быстро дофига или Я уже пьян))) ладно, пересмотрю позже. Спасибо!)

  • @ilyamoharew148
    @ilyamoharew148 Год назад +1

    мужик ты охуенно рассказываешь с тобой программирование становится интересным, спасибо

  • @joesatriani1388
    @joesatriani1388 4 года назад +1

    Самое понятное объяснение. Еще бы окошко студии немножко увеличить чтобы не приглядываться... На экране еще много свободного места)

  • @hello_world_zz
    @hello_world_zz 3 года назад +1

    Классно, спасибо. Прикол (я из Израиля): на 4:50 когда говорил про кошерность я как раз собрался есть бутер колбасой и сыром, зашел в оффис верующий друг в ермолке. лол

  • @Eltar007
    @Eltar007 4 года назад +1

    Вызвать поток, внутри которого делегат, в котором action, который является делегатом, внутрь которого нужно вставить делегат, в котором код на изменение label.... Я потерялся. Уууууууууууу!

  • @leonbishop7404
    @leonbishop7404 4 года назад +2

    Выходит, делегат - это инструмент, позволяющий волан-де-мортизировать метод, и к нему можно обращаться, не называя его имени, правильно?

    • @XpucT
      @XpucT  4 года назад

      Совершенно верно 👍

  • @dgdarkking266
    @dgdarkking266 2 года назад +1

    чот не вдуплю, реально не ясно зачем делегат?
    У тебя есть ряд похожих функций друг на друга
    и тебе надо вызвать ту которую выберет пользователь - много раз она участвует в дальнейших вычислениях
    А так урок классный, спасибо

  • @ivann3135
    @ivann3135 5 лет назад +1

    Спасибо.

  • @andreysokolov297
    @andreysokolov297 2 года назад +1

    Я тебе напишу для чего нужен делегат, только для одного - для callback , все

  • @romanrudman5102
    @romanrudman5102 5 лет назад +1

    Очень полезный урок! Спасибо большое!
    Мне стало интересно по вашему примеру сделать что-нибудь и я попытался объединить информацию из двух уроков. Этот урок и видео о прозрачности контролов. Но столкнулся с проблемой. Я решил немного запарится, создал два UserControl-a и захотел по кнопкам их переключать на основной форме. На основной форме создал "panelContet", в который загружаю UserControl-ы(кнопками вызываю разные). Потом захотелось, чтобы они были с эффектом исчезновения и появления при переключении (как в уроке с прозрачностью). Но не понимаю, какой правильный путь к этому эффекту сделать. Я делаю так:
    Загружаем UserControl в panelContent, всё он на форме =>
    Далее хочу его сменить на другой =>
    Запускаем код исчезновения боксов/лейблов =>
    Очищаем panelContent
    И на загрузке другого UserControl-а я попадаю в задницу, ибо ничего не происходит :D
    private void button3_Click(object sender, EventArgs e)
    {
    //Находим UserControl в pnlContent
    var frm = pnlContent.Controls.Find(selectedContent, true).FirstOrDefault();
    //Создаю новый поток для анимации исчезновения элементов UserControl
    new Thread(() =>
    {
    //Обращаюсь сразу ко всем элементам UserControl
    Parallel.Invoke(() =>
    {
    //Циклом снижаю прозрачность всех элементов
    foreach (var cntrl in frm.Controls)
    {
    //Снижаем прозрачность
    TransparencySub(cntrl);
    }
    });
    }).Start();
    //Не нашел иного метода, как реализовать очистку, мб есть лучше
    new Thread(() =>
    {
    //Пока контролы исчезают, блокирую поток
    Thread.Sleep(1000);
    //Очищаю панель
    pnlContent.Controls.Clear();
    }).Start();
    //Здесь пытаюсь загрузить другой контрол
    new Thread(() =>
    {
    Thread.Sleep(2500);
    AnswerBox ab = new AnswerBox();
    selectedContent = ab.Name;
    pnlContent.Controls.Add(ab);
    ab.Dock = DockStyle.Fill;
    //Находим UserControl в pnlContent
    frm = pnlContent.Controls.Find(selectedContent, true).FirstOrDefault();
    Parallel.Invoke(() =>
    {
    foreach (var cntrl in frm.Controls)
    {
    //Увеличиваем прозрачность
    TransparencyAdd(cntrl);
    }
    });
    }).Start();
    }
    Можно узнать, что я могу делать не так?)

    • @XpucT
      @XpucT  5 лет назад +1

      Привет 🖐
      Вступление и код - это хорошо, но без понимания вступления не могу понять правильно подходишь к коду.
      Давай без кода пока. Опиши полностью, но минимальными требованиями, свою идею.
      Пример:
      Хочу, чтобы на форме была панель. Внутри панели две кнопки. И есть третья кнопка вне зоны панели. Нажимая на неё хочу анимацию тех двух кнопок, которые в панели.
      Напиши идею в таком стиле. Более понятно.
      Исходя из названия UserControl начинаю думать, что Ты слепил свой контрол, но не уверен. Поэтому не путай =) Пиши строже и точнее 👍

    • @romanrudman5102
      @romanrudman5102 5 лет назад

      @@XpucT хорошо, давай попробуем)
      Можно сказать, да, я слепил свой UserControl. Стандартный, через Visual Studio => Проект => Добавить новый элемент => Пользовательский элемент управления(UserControl), но с минимальным функционалом. Я думаю, мне будет так проще организовать логику и сгруппировать контролы внутри этих форм. Представляют из себя максимум ссылки на лейбл/текстбокс, для объявления текста внутри них, не более.
      По итогу, получается так:
      Хочу, чтобы на форме было две кнопки (Menu1, Menu2) и панель(panelContent). Внутри панели переключались два UserControl-а, по нажатию кнопок Menu1 или Menu2. Нажимая на кнопку, например Menu1, один UserControl будет исчезать, а другой появляться.
      Код выше, это то, как я пытался это сделать :)
      Надеюсь в этот раз у меня вышло лучше) Заранее спасибо)

    • @XpucT
      @XpucT  5 лет назад +1

      @@romanrudman5102 Я так понял, что речь идёт о такой концепции, как в Win 10 Tweaker.
      Слева у нас категории, Ты нажимаешь на LinkLabel слева, он скрывает все панели и отображает нужную.
      Нажимаешь на другой LinkLabel и он скрывает снова все панели и показывает нужную.
      В этом идея? Если да, то зачем делать отдельные контролы?
      Всё, что Тебе нужно - это LinkLabel и Panel.
      Ты кажется подходишь к вопросу так, как будто пишешь на WPF. Вот там да, лучше свои делать контролы. Но Твой вопрос там решается с помощью кастомного TabControl. На Windows Forms решается LinkLabel + Panel. Или Я что-то упустил?

    • @romanrudman5102
      @romanrudman5102 5 лет назад

      @@XpucT Видимо да, получается, что идея похожа, но я не очень улавливаю, как вы собирали такое количество контролов на одной форме в разных panel?) Возможно вы создаете их динамически, каждый раз при вызове LinkLabel или же вы все элементы храните на одной форме...?
      Да, я знаю о WPF. Не хотелось бы с ним сталкиваться, совсем не понравился и проблем у него предостаточно внутренних. Хочется на WinForms и по возможности красиво :) Поэтому и пытаюсь реализовать описанный метод выше, но попадаю в просак с потоками, при переключении панелей.
      Но если вы предлагаете оставить эту идею, а как тогда сделать, чтобы при переключении панелей мы увидели, как контролы исчезли с одной панели и только потом выбралась другая и появились контролы на ней?
      У меня выходит, что при переключении он сразу же не дожидаясь исчезновения переходит на вторую панель и отрисовывает появление элементов на второй панели.
      В моем коде есть метод TransparencySub(cntrl);
      который сделан по вашему примеру, в него передаю контролы панелей.

    • @XpucT
      @XpucT  5 лет назад +1

      @@romanrudman5102 закидываешь панель, в ней контролы.
      Сверху закидываешь такую же панель, но уже с другим контентом.
      И таких может быт сколько угодно. Все на одном уровне. Да, неудобно, однако вот так.
      То есть, если возвращаться к контролам первой панели в конструкторе нужно, то это боль. Но вот так вот.
      Нажатие на LinkLabel вызывает метод, который:
      foreach (Panel pnl in Controls.OfType())
      if (pnl.Name.Contains("MainPanel"))
      pnl.Visible = false;
      И при этом показывает нужную панель.
      Двигаться нужно в этом ключе.

  • @aanggelss
    @aanggelss 2 года назад +2

    Спасибо большое что простыми словами объясняешь! Супер! У меня вопрос: как приостановить поток с кнопки и потом опять с кнопки возобновить поток? С этим не могу разобраться...

    • @XpucT
      @XpucT  2 года назад

      ruclips.net/video/DQTmo-xGgZk/видео.html

    • @aanggelss
      @aanggelss 2 года назад +1

      @@XpucT спасибо огромное! Я сделала через if и все получилось! 😀

  • @PK-yd4ki
    @PK-yd4ki 3 года назад +7

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

    • @gennadysmirnov5362
      @gennadysmirnov5362 3 года назад

      обойи вещи

    • @PK-yd4ki
      @PK-yd4ki 3 года назад

      @@gennadysmirnov5362 Что? Обои вещи, Чем? обоими вещами. Учи русский!!!

    • @whata269
      @whata269 2 месяца назад

      ​@@PK-yd4ki обеими

  • @alita9896
    @alita9896 5 лет назад +6

    Спасибо огромное за видео, очень помогло.

  • @Iamnotagenius
    @Iamnotagenius 4 года назад +2

    По поводу делегатов, в основном используется другая их форма - события. Ну то есть события и есть делегаты, только более продвинутые. Ну уж я надеюсь, что никто не отрицает полезность событий)

  • @ЕлизаветаЗлобина-г3н
    @ЕлизаветаЗлобина-г3н 2 года назад +1

    Наконец то!!! Наконец-то я поняла эти ***чие делегаты!!!!!!

  • @-unity-
    @-unity- 4 года назад +1

    По поводу примера из жизни про делегаты. Жили-были крестьяне, которых царское самодержавие сильно угнетало. И тут приходит Ленин со своей советской властью. Крестьяне обрадовались, что сейчас им Ленин этой самой земли-то и прибавит. Вот только как об этом сказать Ленину?
    Есть вариант: каждый из крестьян идёт к Ленину и говорит: "Владимир Ильич, я крестьянин Иванов (Петров, Сидоров), мне бы земли побольше". Потом они почесали репу и решили, что так не пойдёт. Это получается, что вся деревня отправится в Петроград. Тут и красноармейцы по дороге могут остановить и расстрелять (ибо любая власть боится толпы народа), да и работать на земле кому-то нужно.
    Вот крестьяне и решили отправить Ленину одного Пахома. Так и говорят: "Ты, Пахом, будешь нашим делегатом. Как Ленин тебя спросит, мол, зачем пришёл, ты изложишь ему нашу задачу". Тут Иванов кричит: "и про меня не забудь". И Петров ему вторит: "и про меня тоже". Так все крестьяне дружно подписались на делегат. Чтобы как Ленин подписал свой указ, так чтобы он на всех распространился, кто к нему Пахома отправил.

    • @XpucT
      @XpucT  4 года назад

      Неплохо =)

  • @ilkhom.mamadjonov
    @ilkhom.mamadjonov 4 года назад +2

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

  • @DiFiS
    @DiFiS 3 года назад +1

    Нихрена не понял, но то что мне надо было я сделал xD спасибо )

  • @kostya1306
    @kostya1306 2 года назад +1

    Круто! Пошел переписывать свой проект ))

  • @battleBoats
    @battleBoats 5 лет назад +4

    Спасибо за видео! Отлично всё разъяснено в ролике.
    Планируете ли снимать ролики по алгоритмам, паттернам? Было бы здорово коснуться темы DI, IoC -контейнеров.

    • @XpucT
      @XpucT  5 лет назад +2

      Да, после ещё несколько тем в Windows Forms приступим к WPF сразу же на MVVM.

  • @Fonarickable
    @Fonarickable 3 года назад +2

    Из того что знаю я deligate нужен как атрибут метода.
    Такой метод не имеет тела и нужен он чтобы запомнить сигнатуру.
    Например () когда есть коллекция свойств с разными атрибутами и у нас есть метод который возвращает все свойства с одним атрибутом, все свойства с другим и так далее...В этому случае можно написать метод обертку в который передается параметром коллекция и делигативный метод, который проверяет свойство на причастность к атрибуту. И тогда у нас будет не N методов по все атрибутам, а только 2 : один делигат и метод этот делигат использующий.
    Конкретно в тредах делигат видимо используется для того чтобы передать сигнатуру метода.

  • @Colibri_Rent
    @Colibri_Rent 4 года назад +3

    Спасибо огромное за урок, очень классное объяснение. Насчёт написания кода, как по мне, то в строчку лучше, и понятнее. Ещё вопрос, есть ли урок работе с процессами, и сетевое программирование ?

    • @XpucT
      @XpucT  4 года назад

      Будет позже 🤝

  • @tenzo3096tenzo
    @tenzo3096tenzo 2 года назад +3

    Обычно, подобные уроки ставлю на скорость воспроизведения х1.5 или х2. Тут я впервые захотел чуть понизить скорость подачи :)
    А в целом круто, четкий грамотно сформулированный поток инфы.
    Думаю это максимум, что можно уложить в 30 минут, так что за более подробным и вдумчивым перевариванием нужно идти читать документацию.
    Спасибо за труд!

  • @MileshkoVladimir
    @MileshkoVladimir 4 года назад

    А про синхронизацию потоков рассказать, мьютексы, семафоры... В чём между ними разница... Обработки исключений, если что-то в фоновом потоке сломалось... Почему об этом не упомянули? Бывает очень нужно знать в ходе главного потока, как там поживает фоновый, или какие-либо данные, или вычисления, из фонового потока, опрашивать, или получать в главном потоке...

    • @XpucT
      @XpucT  4 года назад

      Я же сказал, что возможностей по обработке просто дикая масса.
      Моя задача в том, чтобы объяснить принцип, показать к кому обращаться и что делать, если чего-то делать нельзя.
      Урок File - рассказывает, что это за класс и что там можно делать с парой примеров.
      Таким образом File.Delete и File.Move достаточно. Далее ученик понимает, что есть и другие методы и будет выяснять Exists и прочие, будучи осведомлённым о том, что в классе много возможностей. Здесь то же самое. Считаю, что самое важное более чем объяснил. Если есть пример сложный, где можно снова поднять тему, то давайте пример 👍

    • @MileshkoVladimir
      @MileshkoVladimir 4 года назад

      @@XpucT Ок, попробую поделиться своим примером. На сколько это будет тут возможно описать.
      Например. Есть главный поток (GUI), в нём мы формируем какие-либо данные (массивы, переменные, списки...) в общем некие пакеты, которые по окончании их формирования складываем в, любым способом организованную, очередь (Queue). А параллельно с этим в фоновом потоке происходит следующее: там вертится бесконечный цикл, в котором проверяется состояние очереди, и если она не пуста, т.е. кол-во элементов в ней больше нуля, то из неё извлекается пакет (по принципу "последним в очередь попал, первым из неё вышел" - FILO), отправляется на некий сервер, получает от сервера ответ, и если ответ корректный и успешный, этот пакет удаляется из очереди, если нет связи, или ответа от сервера, пакет остаётся в очереди... И т.д. по кругу идут итерации... При этом, когда в главном потоке, в эту очередь пакетов добавляется новый пакет, в этот момент (перед самым добавлением) нужно приостановить фоновый поток (я это делал мьютексами, метод .WaitOne(); ), после добавление "отпустить" мьютекс (.ReleaseMutex();), фоновый поток продолжает работу. Таким же образом, когда в фоновом потоке мы получаем ответ от сервера, чтоб эти данные передать главному потоку, делаем так же: .WaitOne(); что-то сделали, или обновили глобальные переменные, .ReleaseMutex();
      Ну, если коротко, то как-то так...)

    • @XpucT
      @XpucT  4 года назад

      @@MileshkoVladimir да, пример хороший. Запишу себе ответвление после темы о базе банных и MySQL в частности, чтобы примеры были адекватными =)

  • @mikhailkhatuntcov1483
    @mikhailkhatuntcov1483 2 года назад +1

    Делегат это ссылка на метод (функцию, порядок неопределённых действий) который будет использован в классе или методе.
    Когда это может быть полезно?
    Когда хочешь сделать код универсальным без модификаций имплементации основного класса и в тоже время сделать код более компактным.
    LINQ прекрасный образчик универсальности.
    Например: вы вычисляете остаток по кредиту за период.
    вы можете всё сделать просто: в одном методе.
    а можете в определенный момент(как параметр метода или как атрибут класса) передать функцию по вычислению процента по кредиту какому-то пользователю класса. При этом вам не надо наследовать класс (в C# можно наследовать только от одного класса). Вы даже можете сделать ваш класс закрытым для модификации.
    По моему скромному мнению: В каком-то смысле делегаты(ссылка на метод) противопоставляет себя одному из принципов ООП: инкапсуляции.

    • @XpucT
      @XpucT  2 года назад +1

      красавчик

  • @diwoolly6293
    @diwoolly6293 5 лет назад +1

    Респект

  • @Konetcs
    @Konetcs 3 месяца назад +1

    Красавчик! Все понятно

  • @anatgu3397
    @anatgu3397 5 лет назад +2

    Не совсем понял причину того , что Вы в своем приложении (win tweaker) используете Thread , для выполнения задач в фоновом режиме . Почему не те же самые таски ? Ведь ту задачу можно было так же поместить в таск , перехватит событие закрытия формы , после чего свернуть приложение , к примеру в трей, и спокойно дожидаться когда оно завершит свою работу. Могу ошибаться , но те же майкросовт - тренеры советуют использовать TPL вместо работы с потоками напрямую.

    • @XpucT
      @XpucT  5 лет назад +2

      Эээ неее.
      Task будет держать основной поток, как ни крути, а нужно, чтобы приложение точно закрылось, если оно фактически по требованию пользователя должно закрыться. При этом, утилита для сжатия файлов должна работать. Она, к слову, штатная, поэтому всё по фен-шую 👍

  • @Pzqmoxwniceb
    @Pzqmoxwniceb Год назад +1

    А закрывать то поток как? Или автоматом закроется?

  • @DrSethGray
    @DrSethGray 3 года назад +1

    А правда-ли, если вызвать асинхронный метод который запускает новый поток и через делегат взвывает этот же метод возможно случайно вернуться назад в прошлое ?😆 О_о Годное видео ) Респект )

  • @4etvero4ka90
    @4etvero4ka90 3 года назад +1

    Кому интересно, название аудио на заднем фоне: Theme From Eternal Sunshine of the Spotless MindScore

    • @XpucT
      @XpucT  3 года назад

      Почти ;)
      Держи ➜ mounika. - let me see jon brion in wonderland

  • @ode2877
    @ode2877 2 года назад +2

    очень круто, многое понял! Осталось понять как сделать поток который бы выполнял задачи по записи и чтению файлов и передавал их в основной поток (привет из Unity и Monobehavior работающих в основном потоке)

  • @jansalk3636
    @jansalk3636 2 года назад +1

    С 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, что я делаю не так? :) И спасибо за видео !!!

    • @XpucT
      @XpucT  2 года назад +1

      Invoke((Action)(() => код
      BeginInvoke не нужен тут.

  • @ВалерияГорц
    @ВалерияГорц 4 года назад +1

    Использовал делегат чтобы на одну кнопку вешать 2 метода(старт/стоп), т.е. кнопка вызывает делегат ,а дальше в методе к ему привязывается другой метод и второй клик по кнопке уже для совсем других действий. Может можно было реализовать проще, но это первое что в голову пришло)

  • @lega3893
    @lega3893 4 года назад

    А есть ли в планах работа с ком объектами? Было бы здорово получить урок про ним. И что-то видосов новых нет). Очень ждём)))

  • @spacerecluse
    @spacerecluse 3 года назад +1

    2. ruclips.net/video/vHqHrf914TA/видео.html
    делегат это не анонимный метод.
    делегат скорее похож на интерфейс но для методов.

    • @spacerecluse
      @spacerecluse 3 года назад +1

      class Program {
      static void Main(string[] args) {
      var woker = new Woker();
      var handJob = (OnWork)woker.HandJob;
      woker.DoWork(handJob);
      var footJob = (OnWork)woker.FootJob;
      woker.DoWork(footJob);
      }
      }
      public delegate void OnWork();
      public class Woker {
      public void DoWork(OnWork work) {
      work();
      }
      public void HandJob() {
      Console.WriteLine("Hand Job");
      }
      public void FootJob() {
      Console.WriteLine("Foot Job");
      }
      }

  • @trumpdmitry2288
    @trumpdmitry2288 5 лет назад +3

    Можешь сделать урок по (Save / Load ) а так же про защиту сохранений ?

  • @Standoffer614
    @Standoffer614 4 года назад +1

    А всё разобрался. чтобы остановить поток надо так делать : Thread100.Suspend();

  • @Ivan-od5qc
    @Ivan-od5qc 3 года назад +1

    В одну строчку легче читается

  • @makzzzimus
    @makzzzimus 3 года назад +1

    я досмотрел твое видео ровно в 12:09
    и у вас в этот же момент было 12:09))

  • @ItMohican
    @ItMohican 2 года назад +2

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

  • @21POPOV
    @21POPOV 4 года назад +1

    Делегат - можно понимать как callback функцию. Строготипизированный колбек дает большую гибкость. Во в первых - он гарантирует, что переданная лямбда соответствует сигнатуре, во вторых - внутри своего метода он позволяет на основании своей сигнатуры писать корректный в плане типов код, что помогает не заниматься отладкой 8 часов, в третьих - не обязательно в метод передавать лямбду, хоть иногда это, безусловно, удобно. list.Sort((a, b) => a.Id.CompareTo(b.Id)) например можно заменить на list.Sort(Sort.ById).
    Делегаты очень широко используются в мире функционального программирования, да и в классическом ООП (например, паттерн шаблонный метод)

  • @evgenyif5287
    @evgenyif5287 2 года назад +1

    Здравствуйте. А как отключить поток, у меня там цикл прервать надо.

    • @XpucT
      @XpucT  2 года назад

      Приветствую 🖐
      ruclips.net/video/DQTmo-xGgZk/видео.html

  • @ЕвгенийПопов-х7ц
    @ЕвгенийПопов-х7ц 3 года назад +1

    Не могу понять ошибку в своем коде. У меня вообще нет такого имени, как Invoke. "Имя Invoke не существует в данном контексте"

    • @XpucT
      @XpucT  3 года назад

      Убедитесь, что используете Invoke не из класса, а из формы, потому что из класса управлять Invoke нельзя.
      Увы, тупо, но это так.

    • @ЕвгенийПопов-х7ц
      @ЕвгенийПопов-х7ц 3 года назад +1

      @@XpucT Спасибо! Видимо, ни один язык программирования не обходится без странностей))

  • @boris.zabolotskikh
    @boris.zabolotskikh 4 года назад +1

    Скажите, для парсинга сайтов (получение страниц и извлечения из них данных) лучше использовать многопоточность или async?

    • @XpucT
      @XpucT  4 года назад +1

      async сегодня в любом вопросе предпочтительнее.

    • @boris.zabolotskikh
      @boris.zabolotskikh 4 года назад +1

      @@XpucT Спасибо!

  • @AndroidsReview
    @AndroidsReview 4 года назад +1

    Обожаю c#, пользуюсь 2008 студией, потому что не люблю выкачивать тонны гигабайт и люблю легкие ide, уже тогда было столько фичей в нем. Тогда наверное он казался языком из будущего.

  • @DushaNews
    @DushaNews 3 года назад +2

    Отличное объяснение! Благодаря тебе у меня единственного в группе курсовая работа будет с потоками))

  • @Hello_world_2020A
    @Hello_world_2020A 3 года назад +1

    2019 - ПОСЛЕДНИЙ УРОК
    Жаль нет новых видео

    • @XpucT
      @XpucT  3 года назад

      Будут ;)

  • @Standoffer614
    @Standoffer614 4 года назад +1

    Спасибо за видео друг ! и Коту привет ! Вопрос . Запустить поток можно так: поток.Start(); а есть ли возможность остановить выполнение потока когда мне нужно ? или как "убить" поток в процессе работы программы ? Спасибо !

    • @igorthelight
      @igorthelight 4 года назад

      поток.Suspend(); - останавливает поток.
      Всё остальное гуглттьс по "C# работа с потоками".

  • @walson4708
    @walson4708 5 лет назад +2

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

  • @AlexanderChel
    @AlexanderChel 4 года назад +1

    Христ, дружище, прошу прощения за тупость, не могу понять где накосячил, когда пишу код для button1_click
    new Thread(() =>
    {
    Action action = () =>
    {
    label1.Text = "123";
    };
    }).Start;
    Выдаёт ошибку "Only assignment, call, increment, decrement, await, and new object expression can be used as a statement." Где собака порылась, не могу понять.

    • @XpucT
      @XpucT  4 года назад +1

      label в потоке точно не стоит менять. Как было сказано в видео, если точно нужно возвращать в родительский поток, то так:
      new Thread(() =>
      {
      Invoke((Action)(() => label1.Text = "123"));
      }).Start();
      А учитывая, что Task сейчас приоритетнее, то лучше вообще так:
      await Task.Run(() => Invoke((Action)(() => label1.Text = "123")));

    • @AlexanderChel
      @AlexanderChel 4 года назад

      @@XpucT Спасибо!!!!!

  • @TbIPDblM
    @TbIPDblM 2 года назад +1

    GeekBrain в помощь :DDDDDDDDDDDDD

  • @_BladeDen_
    @_BladeDen_ 2 года назад +2

    Очень полезное видео - грамотно и доступным языком.

  • @gennadysmirnov5362
    @gennadysmirnov5362 3 года назад +2

    по-людски по-кайфу объясняешь, спасибо!

  • @roman044
    @roman044 3 года назад +1

    Thread thread = new Thread(()=>
    {
    M(label1);
    });
    Я правильно ли понимаю, что после Thread идут скобки в которых пишется делегат, ссылаясь на метод через лямбда выражение ? И почему в делегате нельзя сделать , например , параметры (s,e) как при событии ?

    • @XpucT
      @XpucT  3 года назад

      Сейчас актуальнее делать ➜ await Task.Run(() => {});

    • @roman044
      @roman044 3 года назад

      @@XpucT понял

  • @МихаилСмирнов-т8з
    @МихаилСмирнов-т8з 3 года назад +2

    Огромное спасибо! Очень понятно. Сразу понял как лучше сделать

  • @malyshevslava4664
    @malyshevslava4664 4 года назад +1

    подскажите пожалуйста, как группу потоков thread запустить последовательно? Необходимо чтобы каждый последующий поток стартовал только после завершения предыдущего.

    • @XpucT
      @XpucT  4 года назад

      Посмотрите видео на канале про async, там пример, когда Task создаётся внутри метода, а также Task на сам метод. Это разные вещи и именно таким образом можно запускать их последовательно. Урок 15
      ruclips.net/video/oGxZuq2Ye2Q/видео.html

    • @malyshevslava4664
      @malyshevslava4664 4 года назад +1

      Спасибо за ответ! В данном случае я сглупил. Я пишу расширение для NXopen api, и пытался одну функцию api запустить в разных потоках (функция очень медленно выполняется, и в основном потоке нельзя запускать)...В итоге в отдельном потоке написал цикл обращения к функции. Taskи тоже пробовал, но они к сожалению не такие гибкие из-за необходимости статической обертки.

    • @malyshevslava4664
      @malyshevslava4664 4 года назад +1

      Кстати нашел отличный вариант последовательного запуска потоков с применением функции lock(). Ну и конечно стоит упомянуть что необходимо реализовывать catch (ThreadAbortException) { }. Уж очень долго не мог понять, почему же при закрытии дополнения у меня крашится основная программа.

  • @ЖекаСимаков-у5х
    @ЖекаСимаков-у5х 5 лет назад +2

    Вот прикольная программка про потоки
    Это не я её придумал, честно говоря я просто слизал код, но он довольно таки простой.
    github.com/ultrajeka/Crazy-Buttons.git

    • @ЖекаСимаков-у5х
      @ЖекаСимаков-у5х 5 лет назад

      Есть косяк, при финише нужно нажимать кнопку Стоп, при нажатии на старт программа не перезапускается. Но это такое :)

  • @cryptoeyt
    @cryptoeyt 3 года назад +2

    Очень понятно объясняешь. Про if и else было все очень понятно. Спасибо!

  • @abrikos_yadrony
    @abrikos_yadrony 3 года назад +1

    Делегаты нужны для того, чтобы различные функции в качестве аргументов передавать в другие функции, чтобы потом эти переданные в качестве аргументов функции вызывались когда угодно, идеальный пример - конвейер компонентов Middleware для Asp.Net Core. Если ошибаюсь, поправьте

  • @SCEEF
    @SCEEF Год назад

    Спасибо, перевел свой софт для сжатия игр во много поток, ускорил работу в 2-5 раз)
    Я еще использовал сплит списка строк, на мини списки по 3 элемента, чтобы обработка шла, в каждом потоке по 3 элемента, вместо всех элементов в одном потоке) Мозг лопнул, но по кайфу работает

  • @Собственник-т3к
    @Собственник-т3к 5 лет назад +3

    Давно видео не выходило, надеюсь у вас всё хорошо.
    Был бы рад увидеть уроки по EF (core), либо что-нибудь другое связанное с бд.
    Спасибо!

    • @XpucT
      @XpucT  5 лет назад +1

      Очень занят пока. Будут новые видео ;) Много.