All streams
Search
Write a publication
Pull to refresh
1
0
Анатолий @iRumba

Программист C#

Send message
Вообще-то, на этот вопрос нет формально верного ответа. События выполняются в том потоке, в котором вызывающая сторона сочла нужным их вызвать.

В статье сказано:
В общем обработчики события в примере выше выполняются в потоке, порожденном в методе DoWork(). То есть при генерации события, поток, который его сгенерировал таким образом, дожидается выполнения всех обработчиков.

То есть я указал на приведенный мною пример. Я не стал обобщать, потому что именно различные реализации этого примера я чаще всего вижу в чужом коде. И вот это обобщение, которое вы привели — верное, но без разбора конкретного примера не всем будет понятно. Джуниоров намного больше, чем мидлов и сеньеров. И кода в общем объеме они выдают больше.
Или вы спрашиваете, в каком потоке выполняется делегат во время вызова? Ну так это, в общем-то, очевидно
К сожалению не для всех это очевидно.
При вызове BeginInvoke… на этот вопрос и вы ответа не дали пока.
Как не дал то? написал же что порождаются новые потоки.
Обработчику может хотеться что угодно, набор предоставляемых данных определяется их источником
Само собой, но можно вообще не дать никаких данных тогда. Сказать что чего то изменилось, пусть обработчик сам выясняет что именно. :)

Достаточно Action<T>, где T определяется каждым событием, либо Action<TSource,TArgs>, если я хочу передавать источник.

Вы, кстати, не представляете себе, как меня достал object sender в стандартных событиях.


Почему же не представляю? Представляю. Но иногда за универсальность приходится платить.
Иногда один обработчик может использоваться для аналогичных событий разных типов. И если породитель события нам в данном случае не интересен, то object sender мы оставим без внимания, а вместо этого обработаем аргументы события.

Согласен, чаще всего универсальность в этом излишня.
Сейчас уберу из статьи гневные комментики по поводу Action
Незачем. В универсальном методе, который я предложил, для этого можно не BeginInvoke вызывать, а создать новый поток, в котором вызывать Invoke. Я же написал, статья не про работу с потоками, а про то, в контексте каких потоков выполняются события. К сожалению не все знают ответ на этот вопрос
Да, но экземпляров, порождающих событие может быть несколько и обработчику может захотеться узнать, какой экземпляр породил событие. А так же может быть разное количество и типы аргументов. По этому в конечном итоге у вас таки либо будет несколько универсальных асинхронных порождателя событий, либо вы придете к общему виду, типа

Action<object, MyClass>

Action — это тоже делегат. и казалось бы, почему бы тогда не использовать его?

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

SomeNetEventHandler: EventHandler<SomeNeteventArgs>

и тут мой универсальный метод будет кстати. Я ответил на ваш вопрос?
Согласен. Спасибо за инфу. Сейчас поправлю статью.
в смысле какого типа аргумент будет иметь ваше событие
Вы путаете шаблоны «наблюдатель» и «публикация/подписка»
Я как раз их не путаю
Вообще-то в Observables источник данных понятия не имеет, кто на него подписан.
Не в случае с .net

https://msdn.microsoft.com/ru-ru/library/dd990377(v=vs.110).aspx
Есть такое правило большого пальца, что постоянное создание новых потоков — это большое зло.
Я с вами согласен, но к теме данной статьи это не относится

Может, может (я даже не буду приводить очевидные примеры). В вашем случае идея выглядит как «а давайте запустим все обработчики каждый в своем потоке». Первый же вопрос к это идее — это что делать, если обработчиков очень много.
я не предлагал запускать в отдельных потоках, я предложил запустить в потоке отличном от потока работы генератора.

Почему? Какая разница?
Потому что это не обсервер

Так с большой долей вероятности или гарантированно? А не может так случиться, что он упадет и погребет все приложение?
Не имеет значение… обработка ошибок обработчика событий — дело обработчика событий а не их генератора.
А что у вас будет в качестве T?
Так… Задача вполне конкретна. у меня есть генератор событий, который принимает хандлер типа EventHandler TEventArgs и с ним работает. А в случае с Action<> у вас будет 19 таких генераторов по количеству разновидностей Action. То есть
для Action

для Actionдля Action<T, T>
и тд до 18 аргументов
Класс Action<> не является велосипедом. Только в данном случае он неуместен. Это как «string1» + «string2» + «string3».
Ну да… это как вопрос «а зачем мне использовать готовый велосипед, я изобрету свой»… Да пожалуйста
Ну опишите универсальный способ для многопоточной обработки событий. Мой способ влазит в несколько строк (я не учитываю тут правильную обработку потоков, у меня она неправильная, но я и не ставил цель сделать ее правильной)
А зачем? Он ведь уже есть. Я ведь сказал, что в большинстве случаев будет достаточно этого. Но я не видел пока живых примеров, где не хватало бы EventHandler
События и обсерверы имеют разные области применения. Использовать паттерн «наблюдатель», на мой взгляд, имеет смысл, когда генератору событий нужно знать, кто ожидает оповещений и/или выбирать, кому отправить данное оповещение, а кому нет. Мне вот сбербанк отправляет информацию о моих операциях, а вам о моих не отправляет… зато отправляет о ваших… Вот хороший пример обсервера.
Так в каком же?
В новом
Так вот, без знания ответов на эти вопросы ваша идея опасна.
Идея тут не может быть опасна. Опасна реализация. Но я же предупредил, что все примеры чисто тестовые. Я тут рассматриваю абстрактного коня в вакууме. Вот если бы я написал библиотеку и выложил на гитхаб, то данное замечание было бы уместно.

Так что же будет, если обработчик не обработает ошибку, и она из него вылетит?
Тут все зависит от того, пытается ли обработчик лезть в другие потоки. Если он тихонечко работает в своем конткесте, то с больше долей вероятности он просто упадет и никому об этом не расскажет :)
Если вам все таки хочется об этом узнать, оборачивайте операции обработчика в try catch
я же исправил. принимает а не возвращает… или имеет аргументы если хотите…
Ну хорошо, а если надо больше аргументов события? В этом случае вам придется либо на каждое количество аргументов писать отдельный дженерик метод, либо делать свою собственную реализацию EventArgs, но зачем, если она уже есть?
Я уже ответил на прошлый коммент по этому поводу. Пул потоков не относится к теме данной статьи. Вы можете рулить задачами с шелдером… да чем угодно. Я только предложил идею, как универсализировать систему событий и объяснил где и как работают обработчики

Information

Rating
Does not participate
Location
Томск, Томская обл., Россия
Date of birth
Registered
Activity