Комментарии 14
Разве такие потребности не решаются тем же прометеусом?
А у вас здесь кроме неподдерживаемого кода ещё и создание тредов руками (ещё и без try..catch, что может привести к краху всего процесса) и динамики непонятно зачем и это на первый взгляд только.
Ну и ещё вопросы — кто будет ваш тред останавливать, учитывая, что при завершении процесса в очереди могут быть ещё задачи?
и BlockingCollection был бы здесь более подходящим вариантом с его семафорами и GetConsumingEnumerable, а не Thread.Sleep в цикле как у вас.
Неподдерживаемый код — ну что за инфантильные ярлыки? Ну почему же тредов руками? Первое — тред один. Второе — интересно узнать каким место вы создаете треды? Только не надо писать про Task, он нужен когда создается множество тредов через тредпул(под капотом) и с удобным управлением. Вот насчет try..catch, соглашусь не помешал бы, хотя у меня еще не было в этом месте исключений, но в принципе они возможны. Динамика понятно зачем нужна, чтобы отвязаться от типов, иногда это удобно, например, чтобы писать обработчики для уже существующих или произвольных logItem. Злоупотреблять динамикой не стоит, но иногда и чуть-чуть, где это сэкономит время и силы почему же нет?
Тред из-баграунд, остановится влсед за приложением. Нет цели собрать абсолютно все измерения, зачем? К тому же даже если остановить тред, в очереди останутся события, и что остановка изменит, зачем это?
BlockingCollection был бы здесь более подходящим вариантом
Вполне возможно и лучше, согласен, одно и тоже можно сделать разными способами, выбор способа отчасти вопрос привычки.
А какие потребности решаются прометеусом? Хранение метрик, да решаются
Оп, извиняюсь, я тут имел ввиду AppMetrics и его аналоги.
Неподдерживаемый код потому, что никому кроме вас он не нужен — тот же AppMetrics лучше протестирован и постоянно обновляется/фиксятся баги.
Только не надо писать про Task, он нужен когда создается множество тредов через тредпул(под капотом) и с удобным управлением
Отчего же не надо, когда тут самый подходящий случай? И тредпул как раз-таки не про множество тредов, а совсем наоборот чтобы треды не плодить.
И кстати, если бы использовали нормальную очередь с поддержкой асинхронного ожидания, то выделять тред вообще бы не пришлось.
Но если уж так надо было сделать всё синхронно, то можно выставить TaskCreationOptions.LongRunning
, чтобы тредпул (но только если понадобится!) не стеснялся создать ещё один тред.
Извиняюсь, что несколько резко высказываюсь, с утра воду отключили.
Оп, извиняюсь, я тут имел ввиду AppMetrics и его аналоги.
Может быть, не могу сказать.
никому кроме вас он не нужен
Не следует говорить за всех)
лучше протестирован и постоянно обновляется/фиксятся баги
Вспоминается цитата):
Есть два способа разработки проекта приложения: сделать его настолько простым, чтобы было очевидно, что в нем нет недостатков, или сделать его таким сложным, чтобы в нем не было очевидных недостатков. Ч. Э. Р. Хоар (C. A. R. Hoare)
Отчего же не надо, когда тут самый подходящий случай? И тредпул как раз-таки не про множество тредов, а совсем наоборот чтобы треды не плодить.
Тут наверно можем долго спорить. Как я понимаю основная идея тредпула это ускорить создание потоков, типа кеширования для потоков. Ресурсы под поток выделяются достаточно долго, что легко проверить например создав 10к потоков в цикле. Тредпул на то и пул что содержит уже готовые потоки, которые переиспользуются для выполнения тех же тасков. Поэтому 10к тасков создаются быстро и достаточно быстро обрабатываются на уже готовых потоках. А если у меня 1 поток на все время жизни приложения, зачем же мне таск, хотя не исключаю что его можно использовать. Кстати с тасками и тредпулами тоже есть нюансы, некоторые потоки используются для
если бы использовали нормальную очередь
За это спасибо, подумаю над этим, вполне возможно вы правы, стоит попробовать BlockingCollection.
Извиняюсь, что несколько резко высказываюсь, с утра воду отключили.
Понимаю вас, с утра не обнаружить в кране воду это жестко. Казалось бы 21 век, компьютеры, ракеты, а бесперебойную подачу воды реализовать не могут!
Похоже Вы изобрели https://miniprofiler.com/
del
Настраиваемые логеры, древовидная структура вызовов, замер времени выполнения операции, логирование ошибок, возможность замера времени выполнения без логирования (для ведения статистики) и тому подобное.
Читабельность логов повысилась кардинально. Обложенные логами методы пишут точку вход и выхода из операции, её уникальный номер. Очень помогает в многопоточном коде, избавляет от необходимости россыпи строк типа «Log.Debug(»Begin ...)" «Log.Debug(»End...)".
Есть предварительная договорённость с менеджментом по выводу этого кода в опенсорс с публикацией на гите и NuGet, но пока руки не доходят.
П.С.: В нашем решении асинхронности нет. После каждого изменения в этом коде делаю замеры студийным профайлером — оверхед на логирование минимальный, измеряется долями процента, а качества анализа логов и закрытия саппорт-тикетов повышается кардинально.
Пример вывода профайлера (периодически пишется в логи для выяснения боттлнеков при жалобах на производительность приложения):
Лично я для измерения кода предпочитаю пользоваться линейкой.
А если серьёзно, то в нашем проекте очень похожая структура для сбора статистики, только на Java:
try (var psr = new WatchScope(<...name...>)) { }
.
2)Зачем писать свой логгер, если можно использовать какой-нибудь log4net, который может писать куда угодно и поддерживает параллельную запись в файл из разных потоков.
using — это всего лишь синтаксический сахар, превращаемый компилятором в конструкцию:
try {… } finally { if (obj != null) obj.Dispose(); }
Поэтому не вижу ничего криминального в использовании using там, где это сокращает объём кода, особенно с C#8, который дал возможность упрощать using до одной строки.
Что касается второй части — никто не отменяет log4net. Просто обычные логгеры не умеют логировать время выполнения операций, поэтому есть смысл использовать их в связке с конструкцией, типа той, что предложена автором статьи. Логгер — это абстракция, и не имеет значения куда пишутся записи — файл, база, почта, веб-сервис. Смысл предложенной конструкции совсем не в этом.
Удобный инструмент для измерений C# кода