C# programming. Lesson 19. Multithreading. Part 1

Поделиться
HTML-код
  • Опубликовано: 15 ноя 2024

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

  • @СофияСолнцева-й7щ
    @СофияСолнцева-й7щ 10 лет назад +22

    Прямо праздник какой-то - каждый новый выпуск. Да ещё зимой обычно много праздников... Главное, чтобы у автора энтузиазм делиться своим опытом не пропадал. Я уверен - его жизненная карма обязана при этом становиться лучше. И его английский каким-то волшебным образом тоже.

  • @10nly0ne1
    @10nly0ne1 6 лет назад +14

    7:31 Thread
    12:41 Invoke
    19:31 SynchronizationContext

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

    Это лучший видеоурок по потокам.

  • @Цап-Царап-р8т
    @Цап-Царап-р8т 3 года назад

    Спасибо огромное! Целый день парился. А тут все по полочкам.

  • @dloplb
    @dloplb 6 лет назад

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

  • @antonegorov8803
    @antonegorov8803 6 лет назад +3

    Спасибо за урок. Познавательно. То что искал. Но осталось пара вопросов, хотя они м.б. были рассмотрены позднее.
    Многопоточность с Invoke.
    Ну как бы вопрос с содержимым кнопки "Отмена" отпал сам собой там и правда только _worker.Cancel();
    Так вот:
    1. Для чего в тексте форме после инициализации строки:
    button1.Click += button1_Click;
    button2.Click += button2_Click;
    ????
    С ними нажатие на кнопку старт запускает сразу два потока. И у многих, как и у меня, возникла проблема с остановкой потока, он и прерывался и продолжал выполняться дальше. Решение Закомментировать или удалить эти строки.
    2. Никто не пробовал закрыть форму (Главный "Красный" поток) до завершения синего, пока ProgressBar не заполниться? Вылетает законное исключение.
    Как отловить это исключение, точнее как остановить Синий вспомогательный поток при остановке главного Красного?

  • @НаталияАбргамович

    Очень хорошо - лаконично, ничего лишнего!

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

    С первого раза понял про многопоточность. Браво автор

  • @mishalavik4595
    @mishalavik4595 6 лет назад

    Спасибо за такие каналы как ваш! Очень полезная информация!

  • @АндрейЛ-у7в
    @АндрейЛ-у7в 3 года назад

    Хорошее описание, все четко и по делу!

  • @arkadiyshuvaev
    @arkadiyshuvaev 7 лет назад +12

    Просто отличный урок.
    Кстати, всем, кто найдет это видео уже спустя много лет после публикации (2014). Обратите внимание на комментарий Джона Скита (Aug 18 '15 at 11:22) к своему же ответу: stackoverflow.com/questions/13429129/task-vs-thread-differences?answertab=active#tab-top
    Т.е. сейчас (в наши дни) рекомендовано использование Task.Run.

  • @resolution07
    @resolution07 6 лет назад

    Как же долго я искал именно такой урок. Спасибо вам большое!!!

  • @audesfatum9486
    @audesfatum9486 9 лет назад +3

    Спасибо, очень подробно!

  • @f1sherox
    @f1sherox 10 лет назад +1

    Отличный урок. Спасибо.

  • @ИгорьСикорский-ц3ы

    Спасибо, понравилось!🙂

  • @natunuarat3207
    @natunuarat3207 8 лет назад

    Большое спасибо за урок!
    На моей предыдущей работе все разработчики тоже говорили "шедУлер". Так по-родному звучит ))))

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

    Браво! Спасибо за урок!

  • @VonBreuss
    @VonBreuss 6 лет назад +1

    Вспомнился фильм "Охотники за привидениями".) "Нельзя скрещивать потоки!" =)

  • @L0RDeX
    @L0RDeX 10 лет назад +1

    Очень круто! Большое спасибо!

  • @denyszorin8675
    @denyszorin8675 8 лет назад

    именно то что я искал, спасибо большое !

  • @CatWorldson
    @CatWorldson 10 лет назад +7

    Круто. Tasks бы с async\await действительно не помешал)

    • @Defazze
      @Defazze  10 лет назад +13

      Будет в следующей части )

  • @Александр-х8ш9з
    @Александр-х8ш9з 7 лет назад

    Очень доступно! Спасибо

  • @sashamoroz3569
    @sashamoroz3569 9 лет назад

    Спасибо, отличный урок.

  • @qazyhn94
    @qazyhn94 9 лет назад +6

    вот щас бы про MVC посмотреть)

  • @ТимурАбдулов
    @ТимурАбдулов 9 лет назад

    хорошиее видео подробное у вас получаеться все понятно

  • @Andrei-cv1kn
    @Andrei-cv1kn 3 года назад

    Спасибо!

  • @Rustammv
    @Rustammv 10 лет назад

    ASP.NET MVC это вообще интересная тема. так что буду ждать

  • @alexg9188
    @alexg9188 9 лет назад +1

    Defazze, кол-во просмотров растет. В след видео вставь номер кошелька. С мира по нитке, а тебе приятно.

  • @ОлегКопоть
    @ОлегКопоть 8 лет назад +4

    Большой вопрос: нажимая кнопку стоп messageBox выводится, а вот progressBar не останавливается и доходит до конца. Почему так?

  • @deretor195
    @deretor195 8 лет назад +2

    Насчёт ситуации c прогресбаром в 16:16 : может это происходить из-за того, что к тому моменту когда вылезает окно операции по отрисовке( непосредственно рендерингу) ещё не успели выполниться до конца или не выполнился весь стек команд на отрисовку ?

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

    Ролик отличный, жаль отсутствует ссылка на код. Есть немного неточностей:
    17:00 Добавили строчку " progressBar.Value = progress + 1; ",
    но тогда в цикле при i = 100 условие i

  • @Defazze
    @Defazze  10 лет назад +19

    Вряд ли. Если что и будет, то ASP.NET MVC

    • @galayko_sergey
      @galayko_sergey 9 лет назад +19

      +Defazze Так где же ASP.NET? У вас очень хорошие уроки, с удовольствием смотрел бы серию асп.нет мвс.

    • @lamax847
      @lamax847 6 лет назад +4

      может вернетесь с курсом по asp.net Core

    • @HamsterOfBoo
      @HamsterOfBoo 6 лет назад

      Оператор лилии Брик

  • @YugoRus
    @YugoRus 8 лет назад +2

    Посмотрел видео. Начинающим будет довольно сложно понять. Недостаточно разжевано...
    Вот тут яснее - habrahabr.ru/post/232169/
    Но за видео спасибо! Хорошая работа!

  • @AlexanderŁapkowski
    @AlexanderŁapkowski 3 года назад

    Супер

  • @kaptn6218
    @kaptn6218 7 лет назад +6

    На WPF метод Invoke(action) следует заменить методом Dispatcher.Invoke(action)
    Проверку можно осуществить через вызов метода Dispatcher.CheckAccess() который проверяет есть ли у вызываемого метода доступ к потоку (или просто CheckAccess() == false)
    Таким образом если доступа нету вызываем метод Dispatcher.Invoke(Action callback):
    if(!CheckAccess())
    Dispatcher.Invoke(action);
    else
    action();

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

    Здравствуйте. У меня чёт не работает :)
    Вот как работает эта система: в классе есть функция Work(), которая вызывает Action "ProgressChanged" с параметром, который (Action) в свою очередь связан c функцией worker_ProcessChanged, производящую манипуляции с прогресс баром. И вызывая функцию класса Work() вызывается worker_ProcessChanged через Action.
    Я сделал так же:
    я создал функцию OpNLoad, принимающая на вход OpenFileDialog (он объявлен глобально и определяется по нажатию кнопки). Затем создал Action с тем же типом принимаемого параметра (OpenFileDialog) tryOpen. Далее в нажатии кнопки до определения потока присвоил tryOpen += OpNLoad. Также создал ещё функцию StartLoad, вызывающую Action tryOpen с параметром OpenFileDialog, определённый при нажатии кнопки, и передаю эту функцию (StartLoad) в поток.
    Структурно всё также, как в видео (на 11:35), функция вызывает Action, связанный с другой функцией, и первая функция передаётся в поток, но всё равно ругается на то, что идёт манипуляция с элементом, созданном в другом потоке (ругается всё также на прогресс бар).
    UPD: посмотрел дальше и объявил новый Action, который в теле выполняет действия, затем вызвал это действие через Invoke. На прогресс бар уже не ругается и всё загружает, но всё равно не могу двигать формой в процессе загрузки

  • @F_elixfelicis
    @F_elixfelicis 6 лет назад +1

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

  • @MsAssassinnn
    @MsAssassinnn 10 лет назад

    А будет ли рассмотрен паттерн MVVM, как это было с MVP?

  • @АхмедБахмет223
    @АхмедБахмет223 9 лет назад +3

    А какой код в кнопке Stop? (На видео не показано).
    UPDATE: Разобрался, там _worker.Cancel();

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

      у меня все равно не работает , progressBar не останавливается (((

  • @oleg_dnipro
    @oleg_dnipro 9 лет назад

    Где бы скачать исходник этого урока?

  • @yuryahafonau8373
    @yuryahafonau8373 10 лет назад +3

    молодец

  • @viruslab1
    @viruslab1 9 лет назад +4

    про кнопку стоп то не рассказали ))

  • @tree-service
    @tree-service 3 года назад

    то, что надо.

  • @sexol1235
    @sexol1235 7 лет назад

    спасибо, Бро :)

  • @ReasonX3
    @ReasonX3 10 лет назад

    Скажите пожалуйста, будет ли разсмотрен вопрос отладки многопоточных приложений?

    • @Defazze
      @Defazze  10 лет назад

      не планировал.

    • @РНС_Саакашвили
      @РНС_Саакашвили Год назад

      @@Defazze не написали код обработчика события нажатия второй кнопки

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

    Суппер, +++

  • @zurrrrgggg
    @zurrrrgggg 9 лет назад +2

    Почему не показали код в баттоне Стоп? Мне лично любопытно как остановить поток.

    • @ValeriySherstiuk
      @ValeriySherstiuk 8 лет назад

      private void butStop_Click(object sender, EventArgs e)
      {
      if (_worker != null)
      _worker.Cancell();
      }

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

    Здравствуйте, у меня такая проблема. Когда я закрываю форму, (попробовав в закрытии вызвать метод отмены), то выбрасывается исключение - Доступ к ликвидированному объекту невозможен.
    Имя объекта: "Form1"."
    Как можно с этим бороться? Заранее спасибо. Пробовал окружать Invoke условием if (this.IsDisposed == false)
    {
    this.Invoke(action);
    } Но почему-то не срабатывает

  • @TedFanat
    @TedFanat 6 лет назад

    Ничего не понял, но очень интересно)

  • @ОлегМартынов-н6г
    @ОлегМартынов-н6г 6 лет назад

    спасибо )

  • @mrspacer1
    @mrspacer1 8 лет назад +1

    Поясните, пожалуйста, почему в синхронном коде у нас зависает форма при работе приложения, а при использовании SynchronizationContext не зависает. Ведь в обоих случаях мы используем один поток (красный).
    А еще не понятно зачем нужна проверка InvokeRequired. Что происходит если форма решит что не надо делать Invoke? Мы никогда не попадем в наш метод, но мы же хотим туда попасть!

    • @Defazze
      @Defazze  8 лет назад +2

      +Yuriy Smirnov
      1. При синхронном коде приложение занято выполнением рабочей операции, и из-за этого ему "некогда" реагировать на действия пользователя. Отсюда зависание формы.
      2. Обратите внимание: если Invoke не нужен, то операция вызывается, как обычно, не через Invoke. Т.е. значение прогрессбара в любом сценарии будет увеличено.

    • @mrspacer1
      @mrspacer1 8 лет назад

      +Программирование - это просто, спасибо за ответы. Вот еще пара вопросов, если можно.
      1. Правильно ли я понимаю, что первый и главный поток это SynchronizationContext который сам запускает поток (второй) для WinForms. Мы передаем наши рабочие операции в главный поток и они выполняются как бы "над потоком" формы.
      Иначе не понятно за счет чего используя SynchronizationContext мы избегаем блокировки.
      Если второго потока нет, то программа выполняется линейно. Доходит до рабочей
      операции и должна "повесить" форму.
      2. Не заметил else, извиняюсь, сглупил. Но так ведь еще хуже: операция вызывается не через invoke, значит должно произойти перекрещивание потоков?!

    • @Defazze
      @Defazze  8 лет назад +2

      +Yuriy Smirnov
      1. Главный поток всегда один. Он циклически опрашивает форму, но внутри цикла так же выполняется и рабочий код. Если рабочий код длительный, то естественно что форма "замораживается", потому что главный поток занят выполнением рабочей задачи и опрос формы останавливается. SynchronizationContext - это по сути список делегатов, который тоже находится в этом цикле опроса. Если мы вынесем долгую рабочую операцию в другой поток, а из этого другого потока будем помещать делегаты в этот специальный список, то алгоритм главного потока будет примерно таким:
      а) опросить формы (реакция на действия пользователя, изменение внешнего вида)
      б) выполнить короткий рабочий код, если он есть (длинный то мы вынесли в другой поток)
      в) выполнить делегаты в списке SynchronizationContext (и тут-то происходит изменение прогресс-бара, появление сообщений об окончании работы и т. д.)
      2. Если invoke не нужен, значит, поток один и никакого перекрещивания не происходит )

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

    "As soon as you type new Thread(), it’s over, your project already has legacy code" - Concurrency in C# Cookbook, By Stephen Cleary.

  • @АлександрСмирнов-ш6щ9э

    Можно проще:
    Invoke((Action)(() => { /* Действия в главном потоке */ }));

  • @ТимурАбдулов
    @ТимурАбдулов 9 лет назад +1

    а я на есемблере всего 30 строк вся многопоточность ))) занимает

  • @RasFantasy
    @RasFantasy 10 лет назад

    А как можно передать сам контрол в обработку метода из под другого потока? например метод public void AddRowsDgw(DataGridView Dgw). У меня не получилось это сделать, но сделал некий велик, внутри потока создаю такой же контрол и потом при выходе метода из копии контрола выдаю данные и свойства во внешний контрол не из потока. Может как нибудь по другому можно обойтись ? )

    • @Defazze
      @Defazze  10 лет назад +3

      Не надо создавать контролы не в основном потоке. Это оборачивается гигантским количеством проблем.

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

    почему то у меня ProgrerssChanged выдает null reference exception

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

    Лайк.

  • @jsdev195
    @jsdev195 10 лет назад +1

    Когда будут новые уроки 7

    • @Defazze
      @Defazze  10 лет назад +3

      Сергей Коваль Скоро

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

    По мне так вариант с invoke - очень стрёмное решение с т.з. архитектуры приложения

  • @MKoldun
    @MKoldun 7 лет назад

    Я не понимаю почему вы на 19:18 пишите this.InvokeEx(action); это же эквивалентно Form1.InvokeEx(action); если я не ошибаюсь. Нам же нужно обращаться к статическому методу класса ControlHelp, тобиш ControlHelp.InvokeEx(this, action);

    • @nameless8332
      @nameless8332 7 лет назад

      Потому, что это расширение. Обратите внимание на урок "Три Кита". Где-то во второй половине урока автор расказывает о преимуществе даного подхода.

  • @СерегаБ-б3н
    @СерегаБ-б3н 2 года назад

    Станьте моим учителем) по с#

  • @igor-sukharev
    @igor-sukharev 6 лет назад

    Напоминает свёртку в линейной алгебре. (x, f) => f(x), где x in L, f in L*.

  • @gamerecords_site
    @gamerecords_site 9 лет назад +6

    извините, а неужели сложно выложить и исходники?

  • @СашаАфанасьев-с3с
    @СашаАфанасьев-с3с 9 лет назад

    Ребят как называется библиотека xakep.ru/2010/08/10/52926/ ?

  • @A.M.8181
    @A.M.8181 10 лет назад

    Плиз выложите на дробокс или гугл драйв примеры.

    • @СофияСолнцева-й7щ
      @СофияСолнцева-й7щ 10 лет назад

      Код в примере постоянно эволюционирует - показываются различные в том числе и ошибочные варианты, поэтому конкретного кода для урока здесь иногда не бывает... И в этом уроке почти всё показано, кроме создания объекта _context: SynchronizationContext _context = new SynchronizationContext(); в форме.

    • @Defazze
      @Defazze  10 лет назад +1

      София Солнцева как это не показано, 21:33, обработчик MainForm_Load )

    • @СофияСолнцева-й7щ
      @СофияСолнцева-й7щ 10 лет назад

      Defazze Не знаю. Может у меня код другой, _context без типа данных - это ведь просто идентификатор. У меня он подсвечивался красным, создал объект с одноименной ссылкой - всё скомпилировалось... Не важно.

    • @samson9438
      @samson9438 7 лет назад

      Автор жлобяра, исходник зажал!

  • @ДмитрийН-л9ф
    @ДмитрийН-л9ф 7 лет назад

    люди, код бросьте в коомент, пожалуйста!

  • @orhanaliyev9774
    @orhanaliyev9774 6 лет назад

    У меня не возникло исключения после создания потока))

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

    Я один потерял инициализацию _context?

  • @JohnDoe-pg6eh
    @JohnDoe-pg6eh 5 лет назад

    срэд

  • @ТимурАбдулов
    @ТимурАбдулов 9 лет назад

    а что в C шарп многопоточность есть ? интерестно а в бейсике есть ?

  • @JanryMayers
    @JanryMayers 6 лет назад +1

    Дослушал до места "брик".

  • @samson9438
    @samson9438 7 лет назад

    Автор неужели так сложно выложить исходник?

  • @Abelardinio
    @Abelardinio 9 лет назад +3

    Отличный урок. Спасибо. Но произношение у автора английского просто ппц. После того как он скедъюлер назвал шедулером я чуть не умер))

    • @ГеннадийОлейник-ч4в
      @ГеннадийОлейник-ч4в 9 лет назад +9

      AbelardoTV шедьюлер - английский вариант, скедьюлер - американский (или наоборот)

  • @ragnarl.3780
    @ragnarl.3780 5 лет назад

    Я один заметил, что перед тем как вызывать событие, его нужно проверить на null? Т.е. что у нас есть подписчики.
    Т.к. если их нет а мы вызовем без проверки, будет исключение. У автора ролика я этого не увидел.

  • @ВиталийСучков-у9о
    @ВиталийСучков-у9о 6 лет назад

    Ни_я непонятно. !!!!

  • @РусБ-в
    @РусБ-в 7 лет назад +7

    Что за пример для задротов? Нахрена такие сложные примеры, нахрена этот класс в обучении, нахрена усложнять простое. Типичное неадекватное обучение как в школе, интерес пропадает сразу

    • @bohdanvoitovych1574
      @bohdanvoitovych1574 7 лет назад +4

      Руслан Баскунов прост уроки не для аутов, что и сказано в описании канала.

    • @orhanaliyev9774
      @orhanaliyev9774 6 лет назад +4

      А чо там сложного ?? пара эвентов если смутила так это база без её знания смысл смотреть это видео стремиться к нулю

  • @samson9438
    @samson9438 7 лет назад

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

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

    молодец