Уроки 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 #СиШарп
Отличное объяснение. По делегатам действительно нет ни одного нормального объяснения, только видел пример на коллекции (посчитать к примеру сумму элементов с доп фильтром допустим только четные и т.п.). Эти доп фильтры делать делегатами, и в основном коде вызывать нужный делегат. Но этот пример не живой, ведь вместо всего этого можно использовать лямбда-выражения или вообще 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
{
// обновление данных в таблице
}));
}
};
}
Вот это объяснил))). Сколько видосов про потоки смотрел, этот прям с первого раза зашел. Прям все по человечески объяснил, на простом языке. Спасибо. С меня лайк и подписка
Спасибо вам огромное !!! Вот уже миллион англоязычных туториалов посмотрела, но лучше вас еще нигде не объяснили, ни на каком языке !
Учитель года :) Ты очень хорошо объясняешь! Спасибо, добрый человек :)
Я постоянно не мог найти инфу по этому всему, пытался нарыть инфу из самых странных источников, но тут нашел это видео, и просто любовь с первого взгляда
Про делегаты приведу пример. Есть метод который вызывается для заполнения progressBar, и вот у нас где-то там в другом классе, в другом пространстве имен есть метод который считывает огромный файл, и для этого мы создадим делегат и передадим как параметр, чтоб увидеть прогресс выполнения/чтения файла. Для событий без делегатов не обойтись
Спасибо, посмотрела сначала про async await, где все доступным языком разложено по полочкам
Очень грамотный подход! Очень доволен что нашел ваш канал! Подписка
Ты когда нибудь отдыхаешь? Спасибо тебе!
Просмотрел все уроки. Всё понятно, кратко и по существу. Большое спасибо. Если есть возможность, сделай урок по проблематике защиты кода от дизасемблеров и вообще насколько вероятно сохранить алгоритм программы в секрете.
Про делегаты. Предположим есть комната в которой нет ни окон ни дверей, задача в ней убраться: пропылесосить, протереть пыль. Для решения нужен тот кто уберет комнату и способ в эту комнату попасть. Представим что у нас есть Маша, Петя и Вася - все они могут убрать комнату. Теперь надо их в комнату как-то поместить, есть два варианта: 1) для каждого из них прорубить отдельный вход; 2) сделать ДВЕРЬ.
Предположим, что Маша, Петя и Вася хотят покушать. Есть вариант каждому кушать из своей тарелки, а можно кушать просто с КАСТРЮЛИ.
Нет, не годится. Жду новых примеров. Кстати, после выхода этого видео, спустя какое-то время нашёл применение делегату - доступ к контролу из класса.
Это боль...
@@XpucT Вопрос изначально был зачем? Ну он же вроде как для соплей) Ну типа есть 15 алгоритмов сортировки массива и какой-нибудь PrintTime() для подсчета времени работы каждого алгоритма. Мы делаем PrintTime(Action ... ) и норм, нет? Подобие функциональной обертки из плюсов.
По делегатам, строим аналогию с C++. Функцию нельзя напрямую передать в функцию в качестве параметра. Но можно передать указатель (адрес, "делегат") / Даже в C++ не рекомендуют, в настоящее время, использовать указатели на функцию, а использовать класс Functional - аналог лямбда выражений в C#.
Спасибо автору за такую подачу материала! Очень круто, что объяснение идёт бегло, понятно и НЕ на задротском языке:)
Про язык действительно ценно. Очень живо слушается.
Да-да-да)))
...Это очень важно: это не важно!!! Но у вас останется...
Как-то сжато, немного рвано, дёргано, но при этом класно получается ))
Тайны делегатов раскрыты. Ох сколько я их гуглил. За Parallel отдельное спасибо, это что-то с чем-то.
Очень доходчиво объясняешь, скобки правильно расставляешь, так лучше, чем в строку.
Юмора как раз столько, сколько надо)
Если возможно - уменьши область захвата видео до размера окна виртуалки, т.к. мелкие символы на 720P не видно нормально (Инет 3G, живу вдали от цивилизации)
Присоединяюсь ко всем словам благодарности. Спасибо за проделанную работу!
Хочу дать обратную связь. (13:09) В строчку или в столбик записан код на экране не очень принципиально. Есть только одно пожелание. Увеличьте, пожалуйста, размер шрифта кода. Если смотреть с телефона, то почти ничего не видно. Спасибо!)
PS. На 150% увеличении комфортно (15:35) 🙂
Делегат это грубоговоря ссылка на метод. Все событийная модель на нем построена.
делегат удобен тогда, когда тебе нужен список делегатов (то-есть у тебя есть методы 1,2,3,4,5,6,7) и ты хочешь их выполнять, у тебя есть список с этими методами типа хочу чтобы, выполнялись так 1,2,3,2,2,2,2,2,1,3,4,5 и ну это можно когда количество небольшое прописать вручную, а так существуют делегаты которые можно добавить в список и выполнять когда тебе нужно и в любой последовательности (станки чпу, сценарии какие-то)
Реально живое, человеческое объяснение. Спасибо автору за адекватный канал.
Советую очень серьезно относится к этому уроку, так как сложно без делегатов и без асинхронной/многопоточной программировании
Спасибо за урок, покажи плиз как работать с EF 6(связи, работа с данными и т.п.)
Для меня самое простое объяснение делегата - ссылка на метод или список ссылок на группу методов. Нужны они для удобства, когда какое-то событие может вызывать различные методы, которые в свою очередь определяются в рантайме, а не на стадии компиляции. В зависимости от каких-то условий или действий пользователя мы можем вызвать тот или иной метод, а так же целый список методов, меняя его при необходимости. Написал все нужные методы, а потом просто тупо добавляешь на них ссылку в делегат или убирай из него. Может плюсы делегатов не особо очевидны, когда метод один и он либо вызывается событием, либо нет и третьего не дано. Но когда присутствует большая вариативность поведения, то делегаты могут очень помочь.
Да, абсолютно верно, наконец-то я тоже до этого допёр!) В данном видео не показана одна важная функция делегатов - это расширения списка методов делегата через простую операцию «+=». Это супер удобно при работе в рантайме
Мне понравилось объяснение про ружье и звонок)) А я когда проходил делегаты думал что если я не понимаю его применения на практике, то я че-то не так понял и вообще тупой)
Уроки просто топ. Спасибо
Спасибо! выручил! пиши пожалуйста в столбец -проще понимать.... ну по крайне мере мне)))
Делегат это описание метода - типы входных параметров, тип результата, именно описание а не сигнатура. Отличие описания от сигнатуры - последняя включает имя метода и используется вообще для других целей. Экземпляр делегата это ссылка на метод соответствующий описанию. Реализация?)) События, колбэки и так далее. Я понимаю почему вы конструкции типа delegate(int arg) { return arg; } называете делегатами, вот только это не делегаты и даже не их экземпляры, это анонимные функции/методы, которые потом разбираются компилятором в делегат, сам метод и экземпляр делегата. В первом приближении лямбда выражения это синтаксический сахар анонимных функций, но это не так и у них есть отличия, например анонимные функции могут пропускать объявление аргументов, т.е. Action f = delegate { Console.Write("Hello"); }; f("world"); работает, а лямбда выражения нет, в то же время лямбда могут приводиться как к делегату, так и к дереву выражений, а анонимные функции только к делегату.
Спасибо большое!
Но я хотел услышать про ТреэдПул)))
Спасибо тебе. Сделай пожалуйста шрифт по больше. На телефоне сложно смотреть.
20:42 "New Thread, Старт! *Погнал*"
Чет ору с этого, ахахахахахахахахахахахахахаха. Забавно вы это говорите и когда представляешь тоже ситуация забавная! (типа слишком быстро)
Рождается и ему сразу старт, и он погнал
Отдельная багодарочка за нормально произношение Thread, а не вот эти вот все Сссрэды...)
Thread уже считается legacy code.... нужно использовать Task
Всё правильно 👍
Это просто восхитительно !!! Можно мне такого препода ? А ? Сколько каналов перелопатил, никто так понятно и находчиво не объясняет, просто вау !
К делегатам добавлю некоторое пояснение. Да делегат в простом варианте является конвертером члена класса "метод" в объект, что-бы с методом можно было обращаться как с любым другим объектом (перемеренные, поля, свойства, параметры и тд.). Делегаты из таких структур появились достаточно рано и стали базисом для последующего синтаксического сахара такие как анонимные методы (как мы собираемся обращаться к анонимному методу если у него нету имени), лямбда-выражения (немного функционального программирования из F# и Омега# в C# которые просто красиво написанные анонимные методы) и типы делегаты Action(0...P16) и Func(return,0...P16) (очень сильно упрощают жизнь если нужны всевозможные колбеэки и актуаторы и последнее это события (события и есть делегат только более красиво написанный, события можно и на чистых делегатах написать, толком разницы нету кроме красивости кода). А живой пример смотри на само слово делегат что в переводе на русский является представитель по типу торговых представителей (орифлеймы всякие), послы в посольствах государственных по нормальному это государственные представители и так далее. Если что-то как-то надо представлять каким либо образом это вот делегат. А так это выросло из шаблона проектирования который так и называется делегат (иногда как шаблон делегирования)
В столбец - лучше для понимания. Мы же - изучающие. В строку конечно красивее, но и менее понятно.
У меня есть бутылка и она закрытая. "Открытие крышки" - вот наш делегат!. Мы можем открыть эту бутылку нормальным способом, а можно - ложкой; можно зубами тоже (если они здоровые), некоторые могут и глазом.
Хорошо, что я нарвался на тебя почти в самом начале. Спасибо.
ваще в мелкософте работают извращенцы и они любят придумывать обычным вещам необычные названия)))
delegate это просто адрес конкретного метода ну или объекта, а фишка наверно в том что слово *_delegate_* это красиво заумно и непонятно а кто понял могут делать умный и загадочный вид))))))))))))))))))))))))
Все хорошо, грамотно, свежо, но блин быстро дофига или Я уже пьян))) ладно, пересмотрю позже. Спасибо!)
мужик ты охуенно рассказываешь с тобой программирование становится интересным, спасибо
Самое понятное объяснение. Еще бы окошко студии немножко увеличить чтобы не приглядываться... На экране еще много свободного места)
Классно, спасибо. Прикол (я из Израиля): на 4:50 когда говорил про кошерность я как раз собрался есть бутер колбасой и сыром, зашел в оффис верующий друг в ермолке. лол
Вызвать поток, внутри которого делегат, в котором action, который является делегатом, внутрь которого нужно вставить делегат, в котором код на изменение label.... Я потерялся. Уууууууууууу!
Выходит, делегат - это инструмент, позволяющий волан-де-мортизировать метод, и к нему можно обращаться, не называя его имени, правильно?
Совершенно верно 👍
чот не вдуплю, реально не ясно зачем делегат?
У тебя есть ряд похожих функций друг на друга
и тебе надо вызвать ту которую выберет пользователь - много раз она участвует в дальнейших вычислениях
А так урок классный, спасибо
Спасибо.
Я тебе напишу для чего нужен делегат, только для одного - для callback , все
Очень полезный урок! Спасибо большое!
Мне стало интересно по вашему примеру сделать что-нибудь и я попытался объединить информацию из двух уроков. Этот урок и видео о прозрачности контролов. Но столкнулся с проблемой. Я решил немного запарится, создал два 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();
}
Можно узнать, что я могу делать не так?)
Привет 🖐
Вступление и код - это хорошо, но без понимания вступления не могу понять правильно подходишь к коду.
Давай без кода пока. Опиши полностью, но минимальными требованиями, свою идею.
Пример:
Хочу, чтобы на форме была панель. Внутри панели две кнопки. И есть третья кнопка вне зоны панели. Нажимая на неё хочу анимацию тех двух кнопок, которые в панели.
Напиши идею в таком стиле. Более понятно.
Исходя из названия UserControl начинаю думать, что Ты слепил свой контрол, но не уверен. Поэтому не путай =) Пиши строже и точнее 👍
@@XpucT хорошо, давай попробуем)
Можно сказать, да, я слепил свой UserControl. Стандартный, через Visual Studio => Проект => Добавить новый элемент => Пользовательский элемент управления(UserControl), но с минимальным функционалом. Я думаю, мне будет так проще организовать логику и сгруппировать контролы внутри этих форм. Представляют из себя максимум ссылки на лейбл/текстбокс, для объявления текста внутри них, не более.
По итогу, получается так:
Хочу, чтобы на форме было две кнопки (Menu1, Menu2) и панель(panelContent). Внутри панели переключались два UserControl-а, по нажатию кнопок Menu1 или Menu2. Нажимая на кнопку, например Menu1, один UserControl будет исчезать, а другой появляться.
Код выше, это то, как я пытался это сделать :)
Надеюсь в этот раз у меня вышло лучше) Заранее спасибо)
@@romanrudman5102 Я так понял, что речь идёт о такой концепции, как в Win 10 Tweaker.
Слева у нас категории, Ты нажимаешь на LinkLabel слева, он скрывает все панели и отображает нужную.
Нажимаешь на другой LinkLabel и он скрывает снова все панели и показывает нужную.
В этом идея? Если да, то зачем делать отдельные контролы?
Всё, что Тебе нужно - это LinkLabel и Panel.
Ты кажется подходишь к вопросу так, как будто пишешь на WPF. Вот там да, лучше свои делать контролы. Но Твой вопрос там решается с помощью кастомного TabControl. На Windows Forms решается LinkLabel + Panel. Или Я что-то упустил?
@@XpucT Видимо да, получается, что идея похожа, но я не очень улавливаю, как вы собирали такое количество контролов на одной форме в разных panel?) Возможно вы создаете их динамически, каждый раз при вызове LinkLabel или же вы все элементы храните на одной форме...?
Да, я знаю о WPF. Не хотелось бы с ним сталкиваться, совсем не понравился и проблем у него предостаточно внутренних. Хочется на WinForms и по возможности красиво :) Поэтому и пытаюсь реализовать описанный метод выше, но попадаю в просак с потоками, при переключении панелей.
Но если вы предлагаете оставить эту идею, а как тогда сделать, чтобы при переключении панелей мы увидели, как контролы исчезли с одной панели и только потом выбралась другая и появились контролы на ней?
У меня выходит, что при переключении он сразу же не дожидаясь исчезновения переходит на вторую панель и отрисовывает появление элементов на второй панели.
В моем коде есть метод TransparencySub(cntrl);
который сделан по вашему примеру, в него передаю контролы панелей.
@@romanrudman5102 закидываешь панель, в ней контролы.
Сверху закидываешь такую же панель, но уже с другим контентом.
И таких может быт сколько угодно. Все на одном уровне. Да, неудобно, однако вот так.
То есть, если возвращаться к контролам первой панели в конструкторе нужно, то это боль. Но вот так вот.
Нажатие на LinkLabel вызывает метод, который:
foreach (Panel pnl in Controls.OfType())
if (pnl.Name.Contains("MainPanel"))
pnl.Visible = false;
И при этом показывает нужную панель.
Двигаться нужно в этом ключе.
Спасибо большое что простыми словами объясняешь! Супер! У меня вопрос: как приостановить поток с кнопки и потом опять с кнопки возобновить поток? С этим не могу разобраться...
ruclips.net/video/DQTmo-xGgZk/видео.html
@@XpucT спасибо огромное! Я сделала через if и все получилось! 😀
ХрисТ, ты даже не представляешь себе какой ты молодец. Тебя очень приятно слушать и многие вещи становятся понятнее, чем раньше. Знать и донести это две разные вещи и ты владеешь обоими.
обойи вещи
@@gennadysmirnov5362 Что? Обои вещи, Чем? обоими вещами. Учи русский!!!
@@PK-yd4ki обеими
Спасибо огромное за видео, очень помогло.
По поводу делегатов, в основном используется другая их форма - события. Ну то есть события и есть делегаты, только более продвинутые. Ну уж я надеюсь, что никто не отрицает полезность событий)
Наконец то!!! Наконец-то я поняла эти ***чие делегаты!!!!!!
По поводу примера из жизни про делегаты. Жили-были крестьяне, которых царское самодержавие сильно угнетало. И тут приходит Ленин со своей советской властью. Крестьяне обрадовались, что сейчас им Ленин этой самой земли-то и прибавит. Вот только как об этом сказать Ленину?
Есть вариант: каждый из крестьян идёт к Ленину и говорит: "Владимир Ильич, я крестьянин Иванов (Петров, Сидоров), мне бы земли побольше". Потом они почесали репу и решили, что так не пойдёт. Это получается, что вся деревня отправится в Петроград. Тут и красноармейцы по дороге могут остановить и расстрелять (ибо любая власть боится толпы народа), да и работать на земле кому-то нужно.
Вот крестьяне и решили отправить Ленину одного Пахома. Так и говорят: "Ты, Пахом, будешь нашим делегатом. Как Ленин тебя спросит, мол, зачем пришёл, ты изложишь ему нашу задачу". Тут Иванов кричит: "и про меня не забудь". И Петров ему вторит: "и про меня тоже". Так все крестьяне дружно подписались на делегат. Чтобы как Ленин подписал свой указ, так чтобы он на всех распространился, кто к нему Пахома отправил.
Неплохо =)
очень легко понимаю тебя. продолжай на всех языках пж.
Нихрена не понял, но то что мне надо было я сделал xD спасибо )
Круто! Пошел переписывать свой проект ))
Спасибо за видео! Отлично всё разъяснено в ролике.
Планируете ли снимать ролики по алгоритмам, паттернам? Было бы здорово коснуться темы DI, IoC -контейнеров.
Да, после ещё несколько тем в Windows Forms приступим к WPF сразу же на MVVM.
Из того что знаю я deligate нужен как атрибут метода.
Такой метод не имеет тела и нужен он чтобы запомнить сигнатуру.
Например () когда есть коллекция свойств с разными атрибутами и у нас есть метод который возвращает все свойства с одним атрибутом, все свойства с другим и так далее...В этому случае можно написать метод обертку в который передается параметром коллекция и делигативный метод, который проверяет свойство на причастность к атрибуту. И тогда у нас будет не N методов по все атрибутам, а только 2 : один делигат и метод этот делигат использующий.
Конкретно в тредах делигат видимо используется для того чтобы передать сигнатуру метода.
Спасибо огромное за урок, очень классное объяснение. Насчёт написания кода, как по мне, то в строчку лучше, и понятнее. Ещё вопрос, есть ли урок работе с процессами, и сетевое программирование ?
Будет позже 🤝
Обычно, подобные уроки ставлю на скорость воспроизведения х1.5 или х2. Тут я впервые захотел чуть понизить скорость подачи :)
А в целом круто, четкий грамотно сформулированный поток инфы.
Думаю это максимум, что можно уложить в 30 минут, так что за более подробным и вдумчивым перевариванием нужно идти читать документацию.
Спасибо за труд!
А про синхронизацию потоков рассказать, мьютексы, семафоры... В чём между ними разница... Обработки исключений, если что-то в фоновом потоке сломалось... Почему об этом не упомянули? Бывает очень нужно знать в ходе главного потока, как там поживает фоновый, или какие-либо данные, или вычисления, из фонового потока, опрашивать, или получать в главном потоке...
Я же сказал, что возможностей по обработке просто дикая масса.
Моя задача в том, чтобы объяснить принцип, показать к кому обращаться и что делать, если чего-то делать нельзя.
Урок File - рассказывает, что это за класс и что там можно делать с парой примеров.
Таким образом File.Delete и File.Move достаточно. Далее ученик понимает, что есть и другие методы и будет выяснять Exists и прочие, будучи осведомлённым о том, что в классе много возможностей. Здесь то же самое. Считаю, что самое важное более чем объяснил. Если есть пример сложный, где можно снова поднять тему, то давайте пример 👍
@@XpucT Ок, попробую поделиться своим примером. На сколько это будет тут возможно описать.
Например. Есть главный поток (GUI), в нём мы формируем какие-либо данные (массивы, переменные, списки...) в общем некие пакеты, которые по окончании их формирования складываем в, любым способом организованную, очередь (Queue). А параллельно с этим в фоновом потоке происходит следующее: там вертится бесконечный цикл, в котором проверяется состояние очереди, и если она не пуста, т.е. кол-во элементов в ней больше нуля, то из неё извлекается пакет (по принципу "последним в очередь попал, первым из неё вышел" - FILO), отправляется на некий сервер, получает от сервера ответ, и если ответ корректный и успешный, этот пакет удаляется из очереди, если нет связи, или ответа от сервера, пакет остаётся в очереди... И т.д. по кругу идут итерации... При этом, когда в главном потоке, в эту очередь пакетов добавляется новый пакет, в этот момент (перед самым добавлением) нужно приостановить фоновый поток (я это делал мьютексами, метод .WaitOne(); ), после добавление "отпустить" мьютекс (.ReleaseMutex();), фоновый поток продолжает работу. Таким же образом, когда в фоновом потоке мы получаем ответ от сервера, чтоб эти данные передать главному потоку, делаем так же: .WaitOne(); что-то сделали, или обновили глобальные переменные, .ReleaseMutex();
Ну, если коротко, то как-то так...)
@@MileshkoVladimir да, пример хороший. Запишу себе ответвление после темы о базе банных и MySQL в частности, чтобы примеры были адекватными =)
Делегат это ссылка на метод (функцию, порядок неопределённых действий) который будет использован в классе или методе.
Когда это может быть полезно?
Когда хочешь сделать код универсальным без модификаций имплементации основного класса и в тоже время сделать код более компактным.
LINQ прекрасный образчик универсальности.
Например: вы вычисляете остаток по кредиту за период.
вы можете всё сделать просто: в одном методе.
а можете в определенный момент(как параметр метода или как атрибут класса) передать функцию по вычислению процента по кредиту какому-то пользователю класса. При этом вам не надо наследовать класс (в C# можно наследовать только от одного класса). Вы даже можете сделать ваш класс закрытым для модификации.
По моему скромному мнению: В каком-то смысле делегаты(ссылка на метод) противопоставляет себя одному из принципов ООП: инкапсуляции.
красавчик
Респект
Красавчик! Все понятно
Не совсем понял причину того , что Вы в своем приложении (win tweaker) используете Thread , для выполнения задач в фоновом режиме . Почему не те же самые таски ? Ведь ту задачу можно было так же поместить в таск , перехватит событие закрытия формы , после чего свернуть приложение , к примеру в трей, и спокойно дожидаться когда оно завершит свою работу. Могу ошибаться , но те же майкросовт - тренеры советуют использовать TPL вместо работы с потоками напрямую.
Эээ неее.
Task будет держать основной поток, как ни крути, а нужно, чтобы приложение точно закрылось, если оно фактически по требованию пользователя должно закрыться. При этом, утилита для сжатия файлов должна работать. Она, к слову, штатная, поэтому всё по фен-шую 👍
А закрывать то поток как? Или автоматом закроется?
А правда-ли, если вызвать асинхронный метод который запускает новый поток и через делегат взвывает этот же метод возможно случайно вернуться назад в прошлое ?😆 О_о Годное видео ) Респект )
Кому интересно, название аудио на заднем фоне: Theme From Eternal Sunshine of the Spotless MindScore
Почти ;)
Держи ➜ mounika. - let me see jon brion in wonderland
очень круто, многое понял! Осталось понять как сделать поток который бы выполнял задачи по записи и чтению файлов и передавал их в основной поток (привет из Unity и Monobehavior работающих в основном потоке)
С 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 не нужен тут.
Использовал делегат чтобы на одну кнопку вешать 2 метода(старт/стоп), т.е. кнопка вызывает делегат ,а дальше в методе к ему привязывается другой метод и второй клик по кнопке уже для совсем других действий. Может можно было реализовать проще, но это первое что в голову пришло)
А есть ли в планах работа с ком объектами? Было бы здорово получить урок про ним. И что-то видосов новых нет). Очень ждём)))
2. ruclips.net/video/vHqHrf914TA/видео.html
делегат это не анонимный метод.
делегат скорее похож на интерфейс но для методов.
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");
}
}
Можешь сделать урок по (Save / Load ) а так же про защиту сохранений ?
А всё разобрался. чтобы остановить поток надо так делать : Thread100.Suspend();
В одну строчку легче читается
я досмотрел твое видео ровно в 12:09
и у вас в этот же момент было 12:09))
По моему, необходимость делегатов хорошо объясняет паттерн "Стратегия". Пример такой: У тебя есть определённая стратегия работы. Например: строительство коттеджного посёлка. И у тебя есть проекты строительства домов, дома все похожие, отличаются только в мелочах. Одна из задач в каждом проекте - выкопать котлован под фундамент. Так вот, в каких-то случаях ты можешь загнать туда чернорабочих, и они выкопают (т.к. например, экскаватор туда не проедет). В другом случае на эту же задачу ты отправишь мини-экскаватор. В третьем случае ты отправишь мощный экскаватор с отбойником, (т.к. там к примеру, там находится особо крепкий грунт). Так и в программировании - у нас есть общий метод, с командами - выкопать фундамент, подготовить основание, сделать опалубку, залить фундамент и т.д. а какими методами ты будешь строить каждый конкретный дом - зависит от конкретной ситуации, которая задаётся в конкретном случае и с конкретными условиями.
Делегат - можно понимать как callback функцию. Строготипизированный колбек дает большую гибкость. Во в первых - он гарантирует, что переданная лямбда соответствует сигнатуре, во вторых - внутри своего метода он позволяет на основании своей сигнатуры писать корректный в плане типов код, что помогает не заниматься отладкой 8 часов, в третьих - не обязательно в метод передавать лямбду, хоть иногда это, безусловно, удобно. list.Sort((a, b) => a.Id.CompareTo(b.Id)) например можно заменить на list.Sort(Sort.ById).
Делегаты очень широко используются в мире функционального программирования, да и в классическом ООП (например, паттерн шаблонный метод)
Здравствуйте. А как отключить поток, у меня там цикл прервать надо.
Приветствую 🖐
ruclips.net/video/DQTmo-xGgZk/видео.html
Не могу понять ошибку в своем коде. У меня вообще нет такого имени, как Invoke. "Имя Invoke не существует в данном контексте"
Убедитесь, что используете Invoke не из класса, а из формы, потому что из класса управлять Invoke нельзя.
Увы, тупо, но это так.
@@XpucT Спасибо! Видимо, ни один язык программирования не обходится без странностей))
Скажите, для парсинга сайтов (получение страниц и извлечения из них данных) лучше использовать многопоточность или async?
async сегодня в любом вопросе предпочтительнее.
@@XpucT Спасибо!
Обожаю c#, пользуюсь 2008 студией, потому что не люблю выкачивать тонны гигабайт и люблю легкие ide, уже тогда было столько фичей в нем. Тогда наверное он казался языком из будущего.
Отличное объяснение! Благодаря тебе у меня единственного в группе курсовая работа будет с потоками))
2019 - ПОСЛЕДНИЙ УРОК
Жаль нет новых видео
Будут ;)
Спасибо за видео друг ! и Коту привет ! Вопрос . Запустить поток можно так: поток.Start(); а есть ли возможность остановить выполнение потока когда мне нужно ? или как "убить" поток в процессе работы программы ? Спасибо !
поток.Suspend(); - останавливает поток.
Всё остальное гуглттьс по "C# работа с потоками".
О, христ, я не знал, что ты пилишь уроки). Давно откладывал многопоточку, после шилда так и не вернулся к ней, думаю это жирный намек)
Христ, дружище, прошу прощения за тупость, не могу понять где накосячил, когда пишу код для 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." Где собака порылась, не могу понять.
label в потоке точно не стоит менять. Как было сказано в видео, если точно нужно возвращать в родительский поток, то так:
new Thread(() =>
{
Invoke((Action)(() => label1.Text = "123"));
}).Start();
А учитывая, что Task сейчас приоритетнее, то лучше вообще так:
await Task.Run(() => Invoke((Action)(() => label1.Text = "123")));
@@XpucT Спасибо!!!!!
GeekBrain в помощь :DDDDDDDDDDDDD
Очень полезное видео - грамотно и доступным языком.
по-людски по-кайфу объясняешь, спасибо!
Thread thread = new Thread(()=>
{
M(label1);
});
Я правильно ли понимаю, что после Thread идут скобки в которых пишется делегат, ссылаясь на метод через лямбда выражение ? И почему в делегате нельзя сделать , например , параметры (s,e) как при событии ?
Сейчас актуальнее делать ➜ await Task.Run(() => {});
@@XpucT понял
Огромное спасибо! Очень понятно. Сразу понял как лучше сделать
подскажите пожалуйста, как группу потоков thread запустить последовательно? Необходимо чтобы каждый последующий поток стартовал только после завершения предыдущего.
Посмотрите видео на канале про async, там пример, когда Task создаётся внутри метода, а также Task на сам метод. Это разные вещи и именно таким образом можно запускать их последовательно. Урок 15
ruclips.net/video/oGxZuq2Ye2Q/видео.html
Спасибо за ответ! В данном случае я сглупил. Я пишу расширение для NXopen api, и пытался одну функцию api запустить в разных потоках (функция очень медленно выполняется, и в основном потоке нельзя запускать)...В итоге в отдельном потоке написал цикл обращения к функции. Taskи тоже пробовал, но они к сожалению не такие гибкие из-за необходимости статической обертки.
Кстати нашел отличный вариант последовательного запуска потоков с применением функции lock(). Ну и конечно стоит упомянуть что необходимо реализовывать catch (ThreadAbortException) { }. Уж очень долго не мог понять, почему же при закрытии дополнения у меня крашится основная программа.
Вот прикольная программка про потоки
Это не я её придумал, честно говоря я просто слизал код, но он довольно таки простой.
github.com/ultrajeka/Crazy-Buttons.git
Есть косяк, при финише нужно нажимать кнопку Стоп, при нажатии на старт программа не перезапускается. Но это такое :)
Очень понятно объясняешь. Про if и else было все очень понятно. Спасибо!
Делегаты нужны для того, чтобы различные функции в качестве аргументов передавать в другие функции, чтобы потом эти переданные в качестве аргументов функции вызывались когда угодно, идеальный пример - конвейер компонентов Middleware для Asp.Net Core. Если ошибаюсь, поправьте
Спасибо, перевел свой софт для сжатия игр во много поток, ускорил работу в 2-5 раз)
Я еще использовал сплит списка строк, на мини списки по 3 элемента, чтобы обработка шла, в каждом потоке по 3 элемента, вместо всех элементов в одном потоке) Мозг лопнул, но по кайфу работает
Давно видео не выходило, надеюсь у вас всё хорошо.
Был бы рад увидеть уроки по EF (core), либо что-нибудь другое связанное с бд.
Спасибо!
Очень занят пока. Будут новые видео ;) Много.