Re[4]: .net core и async lock
От: vdimas Россия  
Дата: 06.04.21 11:54
Оценка:
Здравствуйте, Sharov, Вы писали:

V>>Ну и, если требуется только асинхронная блокировка, то SemaphoreSlim — это из пушки по воробьям, слишком тяжеловесно, особенно в свете новомодных TaskValue.

V>>В этом смысле SemaphoreSlim устарел.
S>Что тяжелого с тз асинхронности?

SemaphoreSlim имеет унутре очередь ожидающих "потоков" (т.е. задач), но эта очередь организована через прокси-задачи.
Т.е. каждый вызов WaitAsync создаёт и регистрирует еще один объект Task, что считается тяжеловесным для такой операции.

http://www.rsdn.org/forum/dotnet/7984271.1
http://www.rsdn.org/forum/dotnet/7984267.1
Re[5]: .net core и async lock
От: Ночной Смотрящий Россия  
Дата: 06.04.21 13:57
Оценка:
Здравствуйте, vdimas, Вы писали:

НС>>Методы расширения к чему?

V>К типу SemaphoreSlim.

Это приведет к тому, что использование окажется завязанным на семафор, и легко подменить ее, к примеру, на распределенный лок уже не получится.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: .net core и async lock
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 06.04.21 13:58
Оценка:
Здравствуйте, Sharov, Вы писали:

Можно пришпандорить аналог асихронной очереди

https://docs.microsoft.com/ru-ru/dotnet/standard/asynchronous-programming-patterns/consuming-the-task-based-asynchronous-pattern#asyncproducerconsumercollection
public class AsyncProducerConsumerCollection<T>
{
    private readonly Queue<T> m_collection = new Queue<T>();
    private readonly Queue<TaskCompletionSource<T>> m_waiting =
        new Queue<TaskCompletionSource<T>>();

    public void Add(T item)
    {
        TaskCompletionSource<T> tcs = null;
        lock (m_collection)
        {
            if (m_waiting.Count > 0) tcs = m_waiting.Dequeue();
            else m_collection.Enqueue(item);
        }
        if (tcs != null) tcs.TrySetResult(item);
    }

    public Task<T> Take()
    {
        lock (m_collection)
        {
            if (m_collection.Count > 0)
            {
                return Task.FromResult(m_collection.Dequeue());
            }
            else
            {
                var tcs = new TaskCompletionSource<T>();
                m_waiting.Enqueue(tcs);
                return tcs.Task;
            }
        }
    }
}


С этой структурой данных на месте можно написать следующий код.
C#

Копировать
private static AsyncProducerConsumerCollection<int> m_data = …;

Сделаем сигнальным
m_data.Add(1);


…
await m_data.Take();//Типа Monitor.Enter
......

m_data.Add(1);// Monitor.Exit()
и солнце б утром не вставало, когда бы не было меня
Отредактировано 07.04.2021 7:10 Serginio1 . Предыдущая версия .
Re[6]: .net core и async lock
От: vdimas Россия  
Дата: 06.04.21 19:16
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>>>Методы расширения к чему?

V>>К типу SemaphoreSlim.
НС>Это приведет к тому, что использование окажется завязанным на семафор, и легко подменить ее, к примеру, на распределенный лок уже не получится.

Так и могут потребоваться разные реализации.
Например, SemaphoreSlim подходит когда требуется комбинировать синхронную и асинхронную блокировку.
Правда, без контроля ID потока это может привести к дедлоку, т.к. мьютекс на семафоре(1) нерекурсивный, поэтому, SemaphoreSlim стоит переписать на некий его аналог-мьютекс при необходимости такого комбинирования. Ну и, избавиться от прокси-Task-ов в реализации внутренней очереди, бо это какой-то позор по нынешним временам.

А распределенные блокировки или исключительно асинхронные — это малость другие сценарии.
Их все можно обыграть идентичными методами-расширениями, от которых требуется лишь вернуть IDisposable гарды для using.
(в последних версиях эти гарды могут быть даже value-типами, если не ошибаюсь)
Отредактировано 06.04.2021 19:17 vdimas . Предыдущая версия .
Re[7]: .net core и async lock
От: Ночной Смотрящий Россия  
Дата: 07.04.21 07:46
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Так и могут потребоваться разные реализации.


И зачем это выносить в публичный API?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[8]: .net core и async lock
От: vdimas Россия  
Дата: 07.04.21 13:32
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

V>>Так и могут потребоваться разные реализации.

НС>И зачем это выносить в публичный API?

Для кирпичиков инфраструктуры так принято.
В данном случае будет АПИ методов-расширений над различными объектами.
Re[9]: .net core и async lock
От: Ночной Смотрящий Россия  
Дата: 07.04.21 16:02
Оценка: :)
Здравствуйте, vdimas, Вы писали:

V>>>Так и могут потребоваться разные реализации.

НС>>И зачем это выносить в публичный API?
V>Для кирпичиков инфраструктуры так принято.

Нет.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[10]: .net core и async lock
От: vdimas Россия  
Дата: 07.04.21 20:26
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

V>>>>Так и могут потребоваться разные реализации.

НС>>>И зачем это выносить в публичный API?
V>>Для кирпичиков инфраструктуры так принято.
НС>Нет.

С пробуждением.
OCP из SOLID — давно мейстрим в дотнете, начиная выхода linq и разработанной для него технологии методов-расширений.

Ситуация с тех пор малость забавная — хотя явной сущности "концепт" в дотнете еще нет, но АПИ кирпичиков инфраструктуры теперь разрабатывают так, будто он уже есть.
Типа, в голове держат. ))
В голове компилятора в т.ч., т.к. он реагирует на специические сигнатуры методов и методов-расширений (linq, awaitable и т.д.).

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

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

===============
А да, AwaitableNonDisposable по твоей ссылке теперь тоже лишний, может быть непосредственно заменён на ValueTask.

Да и в целом, попахивает каким-то ненастоящим программированием...
На "отгребись" выполнено, такое можно продавить лишь в среде коллег, резко уступающих в квалификации.
Отредактировано 07.04.2021 20:27 vdimas . Предыдущая версия .
Re[11]: .net core и async lock
От: Ночной Смотрящий Россия  
Дата: 08.04.21 06:17
Оценка: :)
Здравствуйте, vdimas, Вы писали:

НС>>>>И зачем это выносить в публичный API?

V>>>Для кирпичиков инфраструктуры так принято.
НС>>Нет.

V>С пробуждением.

V>OCP из SOLID — давно мейстрим в дотнете, начиная выхода linq и разработанной для него технологии методов-расширений.

Попробуй теперь доказать что OCP и SOLID требует выставлять кишки реализации в публичный API. Я уж не говорю о том что SOLID это совершенно бессистемно надерганный набор принципов и эвристик, и единственный его плюс в том что это модно и молодежно.

V>А да, AwaitableNonDisposable по твоей ссылке теперь тоже лишний, может быть непосредственно заменён на ValueTask.


Лишний. Это писалось до появления ValueTask. Да и сейчас остается поддержка старых платформ, в которых его нет.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[12]: .net core и async lock
От: vdimas Россия  
Дата: 08.04.21 08:12
Оценка: +1
Здравствуйте, Ночной Смотрящий, Вы писали:

V>>С пробуждением.

V>>OCP из SOLID — давно мейстрим в дотнете, начиная выхода linq и разработанной для него технологии методов-расширений.
НС>Попробуй теперь доказать что OCP и SOLID требует выставлять кишки реализации в публичный API.

Кошмар. ))
С каких пор непрозрачные типы стали "кишками"?

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


НС>Я уж не говорю о том что SOLID это совершенно бессистемно надерганный набор принципов и эвристик, и единственный его плюс в том что это модно и молодежно.


За 15-20 лет у тебя ничего не изменилось, смотрю? ))
Но мир IT немного изменился.

Просто ты не понимаешь как именно (или лишь тщательно показываешь позицию, согласно которой и не желаешь понимать "всякую ерунду").
Мир IT от забавного кратковременного хаоса периода от конца 90-х до середины нулевых поступательно возвращается к классике конца 70 — второй половины 90-х.
Принципы SOLID выработались в это время, во времена "классики".
SRP 1979г
Liskov P 1987
OCP 1988 — Мейер, начало эпохи контрактного программирования (частично вы его используете в своей либе по ссылке)
DIP (некоторые регулярно путают с IoC, судя по обсуждениям оных на этом сайте, что тоже кошмар) и ISP — естественные следствия этапов декомпозиции проблем, артефакты назначения ролей подсистемам (например, как часть системного подхода к проектированию в СССР)

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

Ведь Мартин был профессионалом и признанным спецом с 70-х годов, но даже еще в середине 90-х не помышлял кричать о SOLID.
(а SOLID — это, несомненно, крик... вернее, раздражительный окрик, или удар линейкой по пальцам, бгг)

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

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

Остальное ("попробуй доказать", "кишки" и т.д.) выглядит как виденная уже не раз специфическая реакция даже на малейшую критику.
(чем задолбал уже порядком, извиняйте за прямоту)
И говорит о том, что взаимодействовать с тобой возможно только вертикально — когда ты командуешь или когда тобой командуют, но никогда горизонтально, где команда совместно вырабатывает решения.
Тут или ты будешь выдавливать людей, или тебя выдавят.
(это предупреждение молодым/неопытным, как грится)
Отредактировано 08.04.2021 8:37 vdimas . Предыдущая версия . Еще …
Отредактировано 08.04.2021 8:36 vdimas . Предыдущая версия .
Re[13]: .net core и async lock
От: Ночной Смотрящий Россия  
Дата: 08.04.21 09:33
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Кошмар. ))

V>С каких пор непрозрачные типы стали "кишками"?

Ответить на вопрос можешь? При чем тут OCP, если ты предлагаешь приватное поле сделать публичным?

V>И как ты умудрился скипнуть упоминание концептов


Это не имеет отношения к обсуждаемому вопросу, очередное проявление твоей привычки растекаться мысью по древу. У меня не так много времени чтобы писать на твои винегретные простыни подробные ответы.

V>Остальное ("попробуй доказать", "кишки" и т.д.) выглядит как виденная уже не раз специфическая реакция даже на малейшую критику.


А твой ответ выглядит как слив и неспособность аргументировать безаппеляционные заявления, да еще и с хамским переходом на личности.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[14]: .net core и async lock
От: vdimas Россия  
Дата: 08.04.21 11:04
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

V>>Кошмар. ))

V>>С каких пор непрозрачные типы стали "кишками"?
НС>Ответить на вопрос можешь? При чем тут OCP, если ты предлагаешь приватное поле сделать публичным?

OCP-принцип вляется комбинацией критериев Low Coupling/High Cohesion и Protected Variantions.

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

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


V>>И как ты умудрился скипнуть упоминание концептов

НС>Это не имеет отношения к обсуждаемому вопросу, очередное проявление твоей привычки растекаться мысью по древу. У меня не так много времени чтобы писать на твои винегретные простыни подробные ответы.

Я на это уже отвечал — если зашла речь о возможных различных реализациях, то эти реализации могут понадобиться независимо, а не во взаимно-исключительном виде, как ты рассуждал о "подменить реализацию". Ну и, над неким множеством близких по функциональности объектов допустимо рассуждать о "концептах".


V>>Остальное ("попробуй доказать", "кишки" и т.д.) выглядит как виденная уже не раз специфическая реакция даже на малейшую критику.

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

По дизайну был, скорее, вопрос.
Зато насчёт тяжеловесности реализации SemaphoreSlim — тут да, утверждение. Но я его раскрыл, т.е. на безапелляционность утверждение не тянет — несогласные могут аргументировать.
И не вы же SemaphoreSlim разрабатывали, т.е. так близко принимать было не обязательно. ))
Просто опять нарвался на специфическую ответную "аргументацию".
ОК, забей.

На досуге нарисую легковесную реализацию и выложу сюда, т.к. судя по активности коллег оно может быть народу полезно.
Заодно покажет, как тяжеловесные Task-и можно подменять обычными колбэками (делегатами), которые и так уже подаются state-машинкой в awaiter в готовом виде, т.е. доп. накладных расходов можно избежать практически полностью.
Отредактировано 08.04.2021 11:06 vdimas . Предыдущая версия . Еще …
Отредактировано 08.04.2021 11:05 vdimas . Предыдущая версия .
Re[15]: .net core и async lock
От: Ночной Смотрящий Россия  
Дата: 08.04.21 11:32
Оценка:
Здравствуйте, vdimas, Вы писали:

V>В том дизайне приватное поле только одно


Одно не считается?

V>, всё вместе выглядит как фасад над объектом, который уже обладает нужной функциональностью.


Как слой абстракции.

V>По дизайну был, скорее, вопрос.


Как то очень сумбурно и непонятно ты этот вопрос обозначил. Для ясности:
1) Реализация на базе семафора, возможно, не самая оптимальная. Я не настолько погружен в вопрос, чтобы сейчас быть абсолютно уверенным в этом или в обратном
2) Текущий дизайн, возможно, тоже не идеален. И тут довольно странно переключать акцент на мою личность и мое мнение, потому что этот код писал не я.
3) Дизайн в виде extension-методов к SemaphoreSlim точно неудачный, потому что попытка заменить семафор на какую то другую реализацию приведет к полностью разломанной совместимости.

V>На досуге нарисую легковесную реализацию и выложу сюда, т.к. судя по активности коллег оно может быть народу полезно.


Проще и удобнее для всех сделать PR в CJ.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[16]: .net core и async lock
От: vdimas Россия  
Дата: 08.04.21 12:17
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

V>>В том дизайне приватное поле только одно

НС>Одно не считается?

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

OCP не только запрещает изменение уже "готовых" классов, настаивая на альтернативе — их расширении.
Оно прямо поощряет такой подход, в т.ч. с помощью внешних ф-ий.


V>>, всё вместе выглядит как фасад над объектом, который уже обладает нужной функциональностью.

НС>Как слой абстракции.

Где не происходит оперирования абстрактными типами (т.е. семейством их реализаций).

Я хорошо понимаю эти рассуждения, поэтому и начал с contra, т.е. с недостатков лишних слоёв абстракций в донете.

Есть и еще соображения — вся библиотека не выглядит как предназначенная для новичков, которым на месяц-другой дают вылизывать одну GUI-форму или код серверной веб-страницы. Библиотека выглядит как хелпер для фремворковых (ядерных) разработчиков, которые окучивают инфраструктурные и логические слои проектов.

При таких раскладах открывать подробности реализации бывает даже полезно — ведь проект открыт для доработок.
Например, та подробность, что асинхронный мьютекс выполнен поверх слим-семафора является своеобразным TODO для любого использующего библиотеку или просто любопытствующего. Заметь, как резко скакнул дотнет (Core) в кач-ве реализаций инфраструктурных типов после открытия исходников сообществу.
Пару вещей и я туда постил и они вошли в релизы (исправление документации над семейством Vector<N> и решение бага с оптимизацией локальных полей в компиляторе).


НС>2) Текущий дизайн, возможно, тоже не идеален. И тут довольно странно переключать акцент на мою личность и мое мнение, потому что этот код писал не я.


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


НС>3) Дизайн в виде extension-методов к SemaphoreSlim точно неудачный, потому что попытка заменить семафор на какую то другую реализацию приведет к полностью разломанной совместимости.


Предлагалось для всех этих структур создать единый публичный АПИ, в т.ч. не было бы проблем, если у одних методов этот АПИ был в виде методов-расширений, а у других через экземплярные методы. В таком случае в использующем коде (которого много) на уровне исходников ничего не изменилось бы, если тип переменной-"мьютекса" был бы изменён для некоего объекта (в одном месте). Защищаемых подобными мьютексами объектов обычно очень даже счётное количество в реальных проектах, ведь речь тут о длинных блокировках.

Предложение заменить единственную его реализацию на "пространственную блокировку" тут выглядит даже пугающей — поэтому и напрашивается семейтсво с унифицированным АПИ.

Навскидку, даже для озвученной своей альтернативы слим-семафору было бы неплохо попробовать нарисовать сходу парочку реализаций — простой нерекурсивный такой мьютекс и попробовать реализовать рекурсивный, который будет работать только из пользовательских задач, где задача верхнего уровня выполняеется из шедуллера (т.к. потребует валидный Task.CurrentId).


V>>На досуге нарисую легковесную реализацию и выложу сюда, т.к. судя по активности коллег оно может быть народу полезно.

НС>Проще и удобнее для всех сделать PR в CJ.

Это примерно втрое больший объем работы, включая всеобъемлющие тесты и документирование.
Начну, пожалуй, с того, что пообещал. А остальное будет видно... или у меня, или у кого-то из коллег, реально использующих либу, могут дойти руки.
(я эту CJ не использую, но на самописных легковесных awaitable-объектах съел небольшую собаку, поэтому и высказывался по теме)
Отредактировано 08.04.2021 12:21 vdimas . Предыдущая версия .
Re[4]: .net core и async lock
От: vdimas Россия  
Дата: 08.04.21 13:42
Оценка: 18 (1)
Здравствуйте, Serginio1, Вы писали:

UPD
Ой, уже ответил на это сообщение...
Но оставлю подробности, раз написал.

Операция ожидания выполняется потоком из пула потоков. Делегат выполняется рабочим потоком, когда состояние объекта становится сигнальным или истекает интервал времени ожидания.


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


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


Ну да.
В псевдокоде тело потоковой процедуры примерно такое:
void ThreadProc(LPARAM lParam) {
  SomeInternalStruct * s = (SomeInternalStruct *)lParam;

  DWORD result = WaitForSingleObject(s->hEvent, s->timeout);
  (s->*callback)(s->userData, result != WAIT_OBJECT_0);
  free(s);
}

где
struct SomeInternalStruct {
  HEVENT hEvent;
  WaitOrTimerCallback callback;
  void * userData;
  int timeout;
};



S>И на каждый хендл свой поток?


Угу.
В противном случае пришлось бы содержать менеджер таких потоков специально для RegisterWaitForSingleObject, этот менеджер должен быть синхронизируемый мьютексом, потому что не только список таких потоков будет дёргаться из разных вызывающих потоков, но еще у каждого такого потока необходимо вести учёт занятых слотов (всего до 63-х слотов, один должен быть служебный, чтобы разбудить поток и заставить его опять пойти на ожидание с еще одним хендлом). Внутри такого потока будут вызовы уже к WaitForMultipleObjects, но т.к. у разных хендлов разные таймауты, необходимо будет трекать текущее время каждого таймаута, делая вызов WaitForMultipleObjects с минимально оставшимся до истечения ближайшего таймаута временем.

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

Поэтому, сделано грубо, но надёжно и достаточно эффективно для сценария ожидания совсем небольшого кол-ва таких хендлов.
Т.е., для "выкрутиться в единичном случае" оно пойдёт, но где требуется хотя бы теоретическое масштабирование в будущем — лучше не надо.
Отредактировано 08.04.2021 20:14 vdimas . Предыдущая версия . Еще …
Отредактировано 08.04.2021 20:13 vdimas . Предыдущая версия .
Отредактировано 08.04.2021 13:46 vdimas . Предыдущая версия .
Отредактировано 08.04.2021 13:45 vdimas . Предыдущая версия .
Отредактировано 08.04.2021 13:45 vdimas . Предыдущая версия .
Re[12]: SOLID
От: Sharov Россия  
Дата: 09.04.21 12:31
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Попробуй теперь доказать что OCP и SOLID требует выставлять кишки реализации в публичный API. Я уж не говорю о том что SOLID это совершенно бессистемно надерганный набор принципов и эвристик, и единственный его плюс в том что это модно и молодежно.


Требуют, чтобы люди старались по максимум использовать все фишки ООП, а не писать в процедурном стиле +
следили за аккуратность кода в соотв. с принципами SOLID, т.е. почаще рефликсировали о своем коде и SOLID.
Кодом людям нужно помогать!
Re[14]: .net core и async lock
От: vdimas Россия  
Дата: 10.04.21 20:08
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>У меня не так много времени чтобы писать на твои винегретные простыни подробные ответы.


Сергей Тепляков
http://sergeyteplyakov.blogspot.com/2019/12/blog-post.html

Главный навык программиста

Я заметил, что опытных специалистов из разных областей объединяет как минимум одна вещь: осторожность в суждениях.

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

Нужно ли писать тесты? Важно ли качество кода? Какая лучшая степень прожарки мяса? С чем лучше всего сочетается белое вино? Нужно ли делать жим лежа со становой или турника будет достаточно?

Когда я рассматриваю источники информации по некоторой теме я ищу в авторе глубину и осторожность.

Re[15]: .net core и async lock
От: Ночной Смотрящий Россия  
Дата: 11.04.21 09:28
Оценка: +1 :)
Здравствуйте, vdimas, Вы писали:

V>Когда я рассматриваю источники информации по некоторой теме я ищу в авторе глубину и осторожность.


Ну и? Если ты намекаешь на себя, то у тебя нет ни глубины ни осторожности. Ты растекаешься мыслью вширь, при этом совершенно не стесняешься делать далеко идущие выводы даже при недостатке знаний.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[5]: .net core и async lock
От: artelk  
Дата: 11.04.21 12:11
Оценка:
Здравствуйте, vdimas, Вы писали:

V>SemaphoreSlim имеет унутре очередь ожидающих "потоков" (т.е. задач), но эта очередь организована через прокси-задачи.

V>Т.е. каждый вызов WaitAsync создаёт и регистрирует еще один объект Task, что считается тяжеловесным для такой операции.

Не каждый. Если семафор свободен, возвращается переиспользуемый s_trueTask.
А если занят, то полюбому же придется создавать какой-то новый task-like объект в куче и возвращать его (завернутым в ValueTask и т.п.).
Можно подумать в сторону пула таких объектов, но на стороне клиентского кода потребовалось бы явно возвращать их в пул, а это менее удобно.
Если ты что-то другое имел ввиду, просьба развернуть.
Re[15]: .net core и async lock
От: artelk  
Дата: 11.04.21 13:19
Оценка:
Здравствуйте, vdimas, Вы писали:

V>На досуге нарисую легковесную реализацию и выложу сюда, т.к. судя по активности коллег оно может быть народу полезно.

Хотелось бы посмотреть.

V>Заодно покажет, как тяжеловесные Task-и можно подменять обычными колбэками (делегатами), которые и так уже подаются state-машинкой в awaiter в готовом виде, т.е. доп. накладных расходов можно избежать практически полностью.

https://github.com/microsoft/referencesource/blob/master/mscorlib/system/threading/Tasks/Task.cs#L146
А чем таски тежеловесны? Слишком много полей? Методы слишком много делают?

Полагаю, ты завернешь колбак в тип, реализующий IValueTaskSource. Далее завернешь этот тип в ValueTask. Конструктор ValueTask принимает интерфейс, т.е. твой тип, даже если это была структура, будет жить в куче.
Какую-то очередь тебе в любом случае нужно будет делать. SemaphoreSlim работает как FIFO (правда, это свойство не отраженов документации, но лучше бы его воспроизвести). Это будет либо очередь на связном списке, либо что-то с массивами. Если есть основания считать, что твоя очередь лучше — можешь пул реквест сделать. Это деталь реализации SemaphoreSlim, спрятанная от клиентов. Есть большой шанс, что примут.

Еще вариант придумался: попробовать сделать свой собственный хитрый MyValueTask, не требующий боксинга. Очередь будет реализована через связный список массивов (примерно как реализован ConcurrentQueue), в которых по значению будут лежать нужные структуры. MyValueTask будет хранить ссылку на внутренний массив и индекс в нем. Свойство IsCompleted, в частности, будет смотреть в элемент этого массива и возвращать значение оттуда. В теории, должно получится Правда, "отработанные" массивы будут забираться GC только если все инстансы MyValueTask, на них ссылающиеся, удалятся. И от объектов в куче мы не избавились — мы массивы создаем. Переиспользование по кругу массивов (в которых все Task-и completed) не вариант, т.к. мы не знаем, живет ли еще хоть один MyValueTask, ссылающийся на наш массив. Не знаю, будет ли все это заметно эффективней, чем то, как сейчас SemaphoreSlim сделан.
Отредактировано 12.04.2021 8:55 artelk . Предыдущая версия . Еще …
Отредактировано 11.04.2021 13:50 artelk . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.