.net core и async lock
От: Sharov Россия  
Дата: 08.02.21 18:38
Оценка:
Здравствуйте.

А как в .net core обстоят дела с асинхронным локом, есть какой-нибудь примитив а-ля AsyncMonitor?
Мне нужно
lock(syncObj)
{

  await DoAsync()
}


но сделать так на прямую нельзя. Как быть? Есть что-то стандартное\библиотечное?
Тут что-то такое мелькало, но не найду сейчас...
Кодом людям нужно помогать!
Re: .net core и async lock
От: Слава  
Дата: 08.02.21 19:20
Оценка: 4 (1) +1
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте.


S>А как в .net core обстоят дела с асинхронным локом, есть какой-нибудь примитив а-ля AsyncMonitor?


Через SemaphorSlim(1) и Aquire/Release.
Re: .net core и async lock
От: Ночной Смотрящий Россия  
Дата: 08.02.21 20:47
Оценка: 121 (2) +1 :)
Здравствуйте, Sharov, Вы писали:

S>но сделать так на прямую нельзя. Как быть? Есть что-то стандартное\библиотечное?

S>Тут что-то такое мелькало, но не найду сейчас...

https://github.com/rsdn/CodeJam/blob/master/CodeJam.Main/Threading/AsyncLock.cs
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: .net core и async lock
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 09.02.21 07:18
Оценка: 3 (1)
Здравствуйте, Sharov, Вы писали:
https://docs.microsoft.com/ru-ru/dotnet/standard/asynchronous-programming-patterns/interop-with-other-asynchronous-patterns-and-types#tasks-and-wait-handles
и солнце б утром не вставало, когда бы не было меня
Re: .net core и async lock
От: IncremenTop  
Дата: 09.02.21 08:36
Оценка: 4 (1) +3 -4
Здравствуйте, Sharov, Вы писали:

S>но сделать так на прямую нельзя. Как быть? Есть что-то стандартное\библиотечное?


Есть, но скорее всего у тебя неправильная архитектура, раз до такого доходит. Советую пересмотреть и обдумать.
Re: .net core и async lock
От: Kulibin  
Дата: 09.02.21 15:15
Оценка: 4 (1)
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте.


S>А как в .net core обстоят дела с асинхронным локом, есть какой-нибудь примитив а-ля AsyncMonitor?

S>Мне нужно
S>
S>lock(syncObj)
S>{

S>  await DoAsync()
S>}
S>


S>но сделать так на прямую нельзя. Как быть? Есть что-то стандартное\библиотечное?

S>Тут что-то такое мелькало, но не найду сейчас...

Привет это известная проблема у тебя 2-а варианта использовать monitor на прямую, посмотри во что разворачивается lock (синтаксический сахар)
либо вот тебе ссылки на статью как это делается более навороченным способом

https://blogs.msdn.microsoft.com/pfxteam/2012/02/12/building-async-coordination-primitives-part-6-asynclock/
https://blogs.msdn.microsoft.com/pfxteam/2012/02/12/building-async-coordination-primitives-part-5-asyncsemaphore/
Re[2]: .net core и async lock
От: Passerby  
Дата: 20.02.21 16:40
Оценка:
У меня примерно такая же проблема.
Есть функция сторонней библиотеки
public IDisposable AddMessageHandler<Tmessage>(string messageName, Action<Tmessage> handler)
    {
      return _hubProxy.On(messageName, message =>
      {
        var decoded = DataConverter.Decode<Tmessage>(message);
        handler(decoded);
      });
    }

В ней надо написать свои Action<Tmessage> handler для разных событий, которые определяются string messageName.

При этом разного рода события, таких как получение цен, размещение своих ордеров, в случае если цены удовлетворяют условию , не должны мешать друг-другу, т.е. должны быть асинхронными, но события одни и те же, размещение ордеров, не должны быть одновременными, т.к. после каждого размещения изменяется баланс, значение которого используется при размещении ордеров. Думаю сделать просто: Action<Tmessage> handler для события "open_orders" написать
Action<string> aOrdersOpen = async (message) =>
    {
      await Task.Delay(1);
lock (lockOrdersOpen)  
{
//код
}
}

А для события получения изменений цен
 Action<string, Bittrex> AOrderBook = async (message)=>
{
//есть редко вызываемый, только когда есть совпадение условий await асинхронный метод и без lock, чтобы не мешать одновременному потоку цен 
}

Попробовал, работает. Как происходит распознавание синхронный Action<string> или нет не знаю, одного async недостаточно потому await Task.Delay(1);. И код работает потому что нет await окончания работы Action, т.е. не вызывается EndInvoke. То что нет вызова EndInvoke у Action это стандарт для событий?
Отредактировано 20.02.2021 17:18 Passerby . Предыдущая версия . Еще …
Отредактировано 20.02.2021 17:17 Passerby . Предыдущая версия .
Re[3]: .net core и async lock
От: Sharov Россия  
Дата: 26.02.21 19:01
Оценка:
Здравствуйте, Passerby, Вы писали:

P>Action<string> aOrdersOpen = async (message) =>

P> {
P> await Task.Delay(1);

1)Зачем это все делать асинхронно?
2)Возможно, что блокирующая очередь будет чем-то полезна...
Кодом людям нужно помогать!
Re[4]: .net core и async lock
От: Passerby  
Дата: 15.03.21 19:28
Оценка:
Здравствуйте, Sharov, Вы писали:
S>1)Зачем это все делать асинхронно?
S>2)Возможно, что блокирующая очередь будет чем-то полезна...
1. Если приходит информация с сервера, на сервер посылается запрос на выполнение некоторых действий. Если в это время не обрабатывать новые данные с сервера, то после выполнения сервером запроса, будут приходить устаревшие данные, которые были отложены к принятию из-за не асинхронности.
2. Не понял зачем блокирующая очередь.
Re[5]: .net core и async lock
От: Sharov Россия  
Дата: 17.03.21 17:17
Оценка:
Здравствуйте, Passerby, Вы писали:

P>Здравствуйте, Sharov, Вы писали:

S>>1)Зачем это все делать асинхронно?
S>>2)Возможно, что блокирующая очередь будет чем-то полезна...
P>1. Если приходит информация с сервера, на сервер посылается запрос на выполнение некоторых действий. Если в это время не обрабатывать новые данные с сервера, то после выполнения сервером запроса, будут приходить устаревшие данные, которые были отложены к принятию из-за не асинхронности.
P>2. Не понял зачем блокирующая очередь.

В целях синхронизации -- данные обрабатываются по мере поступления. Если не ошибаюсь, возможна разная
конфигурация читателей и писателей -- 1:n, n:n и т.д.
Кодом людям нужно помогать!
Re: .net core и async lock
От: VladCore  
Дата: 17.03.21 17:25
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте.


S>А как в .net core обстоят дела с асинхронным локом, есть какой-нибудь примитив а-ля AsyncMonitor?

S>Мне нужно
S>
S>lock(syncObj)
S>{

S>  await DoAsync()
S>}
S>


S>но сделать так на прямую нельзя. Как быть? Есть что-то стандартное\библиотечное?

S>Тут что-то такое мелькало, но не найду сейчас...

для костыля сойдет. Бест — практис это TaskScheduler с 1м или N рабочимими потоками для той логики которая должна тротлится в один или N потоков максимум. В общем случае. Вы таким образом разделяете ответственность.
Re[2]: .net core и async lock
От: vdimas Россия  
Дата: 06.04.21 02:38
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>https://github.com/rsdn/CodeJam/blob/master/CodeJam.Main/Threading/AsyncLock.cs


А зачем завернули SemaphoreSlim в матрёшку?
Разве методы-расширения не справились бы?

Ну и, если требуется только асинхронная блокировка, то SemaphoreSlim — это из пушки по воробьям, слишком тяжеловесно, особенно в свете новомодных TaskValue.
В этом смысле SemaphoreSlim устарел.
Отредактировано 06.04.2021 2:48 vdimas . Предыдущая версия .
Re[2]: .net core и async lock
От: vdimas Россия  
Дата: 06.04.21 02:53
Оценка: 7 (1)
Здравствуйте, Serginio1, Вы писали:

S>https://docs.microsoft.com/ru-ru/dotnet/standard/asynchronous-programming-patterns/interop-with-other-asynchronous-patterns-and-types#tasks-and-wait-handles


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

И что хреновее всего, здесь участвует межпоточная сигнализация уровня ОС, а этого в общем случае не требуется, т.к. вызывать асинхронное продолжение можно из текущего потока пула, что эффективнее на порядки.
Re[2]: .net core и async lock
От: vdimas Россия  
Дата: 06.04.21 03:02
Оценка: -1
Здравствуйте, IncremenTop, Вы писали:

S>>но сделать так на прямую нельзя. Как быть? Есть что-то стандартное\библиотечное?

IT>Есть, но скорее всего у тебя неправильная архитектура, раз до такого доходит. Советую пересмотреть и обдумать.

Чегой-то? ))
Классический мьютекс — это очередь потоков к ресурсу (обрати внимание, что защищённый мьютексом сценарий назвают "сериализованным").

В кооперативной асинхронщине поверх пула потоков происходящее в точности аналогично, просто очередь переносится из недр ОС в код юзверского уровня исполнения.

Более того, почти всегда очередь можно обслуживать из того же потока, в котором ресурс отпускается, что исключит межпоточную сигнализацию, т.е. не приведёт к профанации кооперативной многозадачности юзверского уровня, ради которой весь этот огород async/await нагородили.

(ИМХО, async/await в управляемых средах — идиотизм сам по себе, бо сответствующая потоковая модель могла быть применена средой исполнения автоматически, без разметки ключевыми словами со стороны программера)
Отредактировано 08.04.2021 13:04 vdimas . Предыдущая версия .
Re[2]: .net core и async lock
От: vdimas Россия  
Дата: 06.04.21 03:10
Оценка:
Здравствуйте, Kulibin, Вы писали:

K>https://blogs.msdn.microsoft.com/pfxteam/2012/02/12/building-async-coordination-primitives-part-5-asyncsemaphore/


Г-но мамонта из 2012-го.
Сейчас стоит сделать очередь простых пар {callback:delegate, configuredAwait:bool}, без прокси-задач TaskCompletionSource, как по ссылке.
См IValueTaskSource.
Re[3]: .net core и async lock
От: Sharov Россия  
Дата: 06.04.21 07:12
Оценка:
Здравствуйте, vdimas, Вы писали:

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

V>В этом смысле SemaphoreSlim устарел.

Что тяжелого с тз асинхронности?
Кодом людям нужно помогать!
Re[3]: .net core и async lock
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 06.04.21 08:15
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, Serginio1, Вы писали:


S>>https://docs.microsoft.com/ru-ru/dotnet/standard/asynchronous-programming-patterns/interop-with-other-asynchronous-patterns-and-types#tasks-and-wait-handles


V>Никогда так не делай. ))

V>Унутре вызывается RegisterWaitForSingleObject, а этого вызова надо избегать — он морозит по одному потоку на каждый такой хендл.

V>И что хреновее всего, здесь участвует межпоточная сигнализация уровня ОС, а этого в общем случае не требуется, т.к. вызывать асинхронное продолжение можно из текущего потока пула, что эффективнее на порядки.


Ну судя по описанию вызовется делегат в пуле потоков. Ничего морозиться не будет
https://docs.microsoft.com/ru-ru/dotnet/api/system.threading.threadpool.registerwaitforsingleobject?view=net-5.0

RegisterWaitForSingleObjectМетод помещает указанный делегат в очередь пула потоков. Рабочий поток будет выполнять делегат при возникновении одного из следующих событий:
Указанный объект находится в сигнальном состоянии.
Интервал времени ожидания истекает.
RegisterWaitForSingleObject Метод проверяет текущее состояние указанного объекта WaitHandle . Если состояние объекта не сигнальо, метод регистрирует операцию ожидания. Операция ожидания выполняется потоком из пула потоков. Делегат выполняется рабочим потоком, когда состояние объекта становится сигнальным или истекает интервал времени ожидания. Если timeOutInterval параметр имеет значение, отличный от 0 (ноль), а executeOnlyOnce параметр — false , таймер сбрасывается каждый раз, когда событие получает сигнал, или истекает интервал времени ожидания.


По твоему поток морозится на ожидании сигнала или таймаута.
И на каждый хендл свой поток?
и солнце б утром не вставало, когда бы не было меня
Отредактировано 06.04.2021 8:45 Serginio1 . Предыдущая версия .
Re[3]: .net core и async lock
От: Ночной Смотрящий Россия  
Дата: 06.04.21 10:31
Оценка:
Здравствуйте, vdimas, Вы писали:

V>А зачем завернули SemaphoreSlim в матрёшку?

V>Разве методы-расширения не справились бы?

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

V>>А зачем завернули SemaphoreSlim в матрёшку?

V>>Разве методы-расширения не справились бы?
НС>Методы расширения к чему?

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

S>Ну судя по описанию вызовется делегат в пуле потоков.


Верно.


S>Ничего морозиться не будет


Ты же сам ниже оставил объяснение:

S>Операция ожидания выполняется потоком из пула потоков. Делегат выполняется рабочим потоком, когда состояние объекта становится сигнальным или истекает интервал времени ожидания. Если timeOutInterval параметр имеет значение, отличный от 0 (ноль), а executeOnlyOnce параметр — false , таймер сбрасывается каждый раз, когда событие получает сигнал, или истекает интервал времени ожидания.

S>[/q]

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


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


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


Да, что малость забавно, ведь WaitForMultipleObjects может ожидать до 64-х хендлов.
Видать, не стали заморачиваться.
Отредактировано 08.04.2021 13:00 vdimas . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.