Pull to refresh
4
0.9
Send message

При таком отношении расходов к доходам имеет ли смысл платить 6% с оборота? Платили бы 15% с прибыли и уменьшили бы налог в 5 раз?

Как утверждает калькулятор, черная дыра планковской массы, как в батарейке, испарится за 4.8E-40 секунд, то есть сразу. А килограммовая за 4.7E-17 секунд, то есть в сто секстиллионов раз медленнее - но опять же сразу.

Я бы тоже минуснул, но мне нельзя.

Помимо фейспальмово начальной темы, вопросы по которой на Stack Overflow закрывают как дубликаты в течение пары минут, здесь куча всякой другой фигни.

Используется FSO, значит код не запустится на Office for Mac.

Делается вид, что все переменные культурно объявлены. На самом деле все переменные объявлены внутри ReplaceTextInFiles(), где они не используются. А используются они в ProcessFiles(), где они не объявлены. Если поставить Option Explicit наверх, где оно всегда должно быть, всё это перестанет компилироваться, и поделом.

Используется странный способ выявления файлов xlsx, который будет срабатывать на любых файлах, у которых .xlsx встречается где угодно в имени, вместо правильного fs.GetExtensionName.

Используется конструкция If LCase(file.Name Like "*.xlsx*"), которая не имеет смысла. Оператор Like возвращает True или False, LCase неявно преобразует это в строку "True" или "False", возвращая строку "true" или "false", после чего эта строка анализируется через If, для чего она неявно парсится обратно в True или False.

Используется простейшая форма Replace, которая заменит не только номер договора, но и всё остальное, что случайно содержит что-то вроде номера договора где-то в середине - концептуально та же история, что с выявлением файлов xlsx. А выявление даты, к тому же, имеет шанс выдать не только ложное срабатывание, но и ложное несрабатывание, если оная дата где-то отформатирована иначе.

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

У очереди, куда приходят «умершие» сообщения, можно указать время их жизни (message-ttl), а уже упомянутые свойства dead-letter-exchange и dead-letter-routing-key задать так, чтобы сообщения возвращались в исходную очередь. В результате сообщения будут автоматически отправляться на повторную обработку с заданной задержкой.

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

То, что попало в DLX, ведь не блокирует обработку того, что продолжает поступать в изначальную очередь. А сквозной порядок через две очереди Rabbit не поддерживает, если не ошибаюсь.

Мало женщин в IT по разным социальным причинам, утверждает статья, ссылаясь на различные исследования (подрывая, однако, доверие к себе использованием таких слов, как "профессорка").

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

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

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

Поэтому печальна судьба тех стран, которые, обнаружив увеличение гендерного неравенства в отраслях своих экономик, делают вывод, что они плохо стараются на поприще обеспечения равных гендерных прав, и начинают стараться лучше. Потому что от этого неравенство увеличивается и возникает порочный круг обратной связи "мы плохо стараемся", бросая государство во всё более безумные инициативы по обеспечению "равенства".

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

выходит 1,5-2 мВт, это около 15 000 ₽

Ничего себе у вас расценки, 15 миллиардов рублей за киловатт-час.
Хорошо хоть, что принтеры такие экономные.

Tак из того что я в этой и прошлой статьях нарисовал (а вы проверили) действительно видно что поток не блокируется в обоих случаях и когда мои

Task Main и Task SomeMethodAsync1 выполняются одновременно

и когда они выполняются последовательно, кто же с этим спорит-то?

Вы не то чтобы с этим спорите, вы (и в прошлой статье, и в этой) сначала говорите "проверим, блокируется ли поток", а потом показываете код, суть которого - что некий новый поток либо фигурирует, либо всё обходится без него.

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

я тоже заметил что пропал первый поток (ID=1), мне как раз было интересно услышать комментарий по этому поводу

Как вы, конечно, знаете, вызов любой асинхронной функции начинается синхронно (а значит, совершенно точно на том же потоке, что делает вызов). Выполнение становится асинхронным, когда в цепочке вызовов встречается первый незавершённый await.

Первый незавершенный await у вас перед Task.Yield(), соответственно там вызов и перестаёт быть синхронным. Вовлекается конечный автомат, которому говорят, откуда потом надо продолжать, и контекст синхронизации решает, на каком потоке конечный автомат это будет делать. Поскольку у вас консольное приложение, то вы используете консольный контекст синхронизации, а он размещает асинхронные продолжения на потоках из пула. Поэтому до строчки await Task.Yield у вас один поток, а после другой.

Когда у вас не было await перед SomeMethodAsync1, всё работало точно так же относительно первого незавершённого await, смена потока, выполняющего продолжение, происходила на том же await Task.Yield. Разница только в том, что без await ваши Task Main и Task SomeMethodAsync1 выполняются одновременно, а не последовательно, что вам чаще всего не надо (Fire and Forget по типу 1, плюс с неожиданным параллелизмом в силу характера работы консольного контекста синхронизации).

Вообще-то ASYNC придумали чтобы можно было писать AWAIT. Зачем нужен AWAIT, вы почему-то скромно умолчали. А у меня речь идет именно про AWAIT

Под словами "async придумали" я имел в виду "придумали механизм асинхронных вызовов в .NET", а не "придумали ключевое слово async в C#".

Ключевые слова async и await в C# (Async и Await в VB) - это часть одного синтаксического пакета, и говорить о том, что их придумали как самоцель, некорректно. Их придумали, чтобы обеспечить удобное использование механизма асинхронных вызовов из языка. Указывать на различия между ними - примерно как указывать на различия между операторами + и =.

Ключевое слово async разрешает компилятору преобразовывать тело метода в конечный автомат, а ключевое слово await указывает, в каких местах это делать. Одно бесполезно без другого, поэтому вы не можете использовать ключевое слово await в методе, который не помечен ключевым словом async. Наоборот можно, но бессмысленно, поэтому при попытке сделать это вы получаете warning от компилятора.

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

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

Нет, async придумали не для того, чтобы "экономить потоки", а для того, чтобы их не блокировать.

Нет, добавление await не превращает вызов в "синхронный". Поэтому его так никто и не называет. Если вы хотите увидеть синхронный вызов асинхронной функции, смотрите тут.

Нет, добавление await и его эффект - не таинственное знание и не "Преобразованный Асинхронный вызов", а наиболее обыденный (если угодно, "непреобразованный") способ использования асинхронных функций.

Нет, добавление await не приводит к выполнению всего кода на одном потоке. Распределением Task по потокам занимается контекст синхронизации. Самый простой способ увидеть это в вашем неправильном, подогнанном под ответ примере - добавить строчку Console.WriteLine($"TrID={Thread.CurrentThread.ManagedThreadId}"); в SomeMethodAsync1, прямо перед await Task.Yield();, что даст вам:

TrID=1
TrID=4
MethodIter=0
MethodIter=1
MethodIter=2
...

Вы, получается, строки совсем не используете в программе, только байтовые массивы? Это же очень сильно неудобно? И выгоды никакой, потому что перевод кодировки должен или автоматически происходить, через объект Connection к базе, или вручную в момент отправки наружу через StreamWriter, настроенный на нужную кодировку?

Выражение-то корректно, только имеет тип ReadOnlySpan<byte>. Его в строковых операциях не использовать нигде, только в стрим писать байтами и остаётся.

Так не бывает строк таких в дотнете. string всегда в UTF-16. Который вполне себе тоже содержит символы длиной от двух до четырех байт.

Дело не в самом железе, а в точке достижения незавершенного await (в случае с железом это будет как раз точка достижения железа).

Каждый await вниз по цепочке вызовов выполняется синхронно, до первого await, который не сможет выполниться синхронно и задействует вместо этого конечный автомат. В этот момент вызов вернется в начало цепочки, и поток, который этот вызов начал (и у которого теперь на руках незавершенный await) окажется свободен. Он вернётся туда, откуда пришёл - в случае с консольным приложением в тредпул, в случае с winforms - в петлю сообщений. И будет там заниматься своими делами, а не сидеть и ждать, пока вернётся его незавершённый await. Поэтому можно говорить, что there is no thread, которая сидит и ждёт.

Этот принцип вы никак не опровергаете своими примерами.

Асинхронная операция не создаёт поток в том смысле, что его создаёт не она. Поток создаёт (или не создаёт) контекст синхронизации.

из какого нафик железа

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

Прочтите хотя бы до середины, до слов

The write operation is now “in flight”. How many threads are processing it?
None.
There is no device driver thread, OS thread, BCL thread, or thread pool thread that is processing that write operation. There is no thread.

При этом ваши выводы - о том, что код продолжил выполняться на другом потоке, чем до этого - совершенно ортогональны статье и никак не опровергают и не подтверждают её.

Ещё раз, суть статьи и фразы "there is no thread" - объяснить, что нет никакого потока, который сидит и больше ничего не делает, кроме как ждёт, пока вернётся await. Потому что людей это беспокоило и они хотели этот ждущий поток освободить. И всё это никак не связано с тем, на том же или на другом потоке продолжит выполняться код после возврата await-а.

"Сейчас" - в контексте критикуемой вами статьи и её главной мысли - это пока выполняется ваш await, который вы уже вызвали и который уже ушёл из вашего кода, через фреймворк, через драйвер в железо, и пока не вернулся. Утверждение "There is no thread" - это про то, что в этом "сейчас" нет никакого потока, который занимается ожиданием возвращения вашего await.

А вы пытаетесь это утверждение опровергнуть, приводя примеры про "после", когда вышеупомянутый await наконец вернулся из железа, через драйвер, через фреймворк в ваш код, и следующий за ним код вдруг выполняется в другом потоке. Что совершенно иное явление.

1
23 ...

Information

Rating
1,392-nd
Registered
Activity