|
Уважайте чужое время
75 / 23 / 8
Регистрация: 01.02.2013
Сообщений: 191
|
||||||
Получение результата вызова функции из очереди16.08.2021, 21:22. Показов 4840. Ответов 17
Метки нет (Все метки)
Есть некая функция, которая получает данные, обрабатывает и возвращает результат обработки. Функция, как есть =)
Данные, которые она получает, можно обрабатывать только по очереди (где-то увидел интересный тип очереди: BlockingCollection<T>). Одновременная обработка возможна, но приведёт к ооочень большим затратам по памяти и процессору, т.к. создание объектов обработчика — дорогое занятие в этом плане, поэтому желательно исходить из того, что это невозможно, но варианты рассмотрю. Итого, я хочу не плодить обработчики, а пользоваться одним, но последовательно, притом, что вызовы обработчика происходят асинхронно. Если обработчик начинает работу, а работа уже шла, то он благополучно падает на середине пути. Идея с очередью показалась близкой с искомой, но моя проблема в том, что я не могу сообразить, как мне связать добавление объекта в очередь и получить выполнение функции с аргументом в виде этого объекта из очереди для конкретного вызова? Либо, я вполне вероятно, упускаю какой-то более разумный подход к организации подобного процесса. Рабочего кода относящегося к теме особо нет, поэтому далее условный код, коротко иллюстрирующий искомое:
Точно есть способ лучше, подскажите плз, или хотя бы пните в нужную сторону =)
0
|
||||||
| 16.08.2021, 21:22 | |
|
Ответы с готовыми решениями:
17
Встраивание результата функции в место ее вызова Получение результата скалярной функции Sql Server из VBA Получение результата из функции. Поиск нужного значения по матрице |
|
Модератор
|
|
| 16.08.2021, 21:34 | |
|
big1991, вы как бы противоречите сами себе.
Вам нужна асинхронность, но обработка последовательная.... Последовательная по какой причине? Если для обработки следующего элемента нужны результаты обработки предыдущего, то здесь никакую асинхронность не запихнёшь. Максимум можно занять один поток и в нём последовательно запускать задачи в порядке элементов. Если же последовательность нужна для возврата результатов в той же последовательности, то ваше предположение в конце поста - один из возможных вариантов реализации.
0
|
|
|
Уважайте чужое время
75 / 23 / 8
Регистрация: 01.02.2013
Сообщений: 191
|
|
| 16.08.2021, 21:44 [ТС] | |
|
Этим обработчиком пользуются разные службы и разные инстансы одинаковых служб, которые работают независимо друг от друга.
Обработчик их обрабатывает последовательно, т.к. он один, а вот запросы поступают вразнобой и иногда одновременно, что заставляет обработчик захлебнуться. Их время блокировки даже при одном единственном обработчике несущественное, поэтому на данный момент меня только интересует возможность отправлять запросы асинхронно и дальше выполнять независимые вычисления, пока запрошенное то значение не понадобится, а далее я уже подумаю, как плодить обработчики не тормозя работу и снижать нагрузку на очередь (мб буду добавлять их при достижении очереди выше порога). Смысл не в том, чтобы забирать ответы в том же порядке, а в том, чтобы каждый вызов забрал точно своё значение потокобезопасным образом. А в приведённом участке этого не происходит.
0
|
|
|
Модератор
|
|
| 16.08.2021, 21:57 | |
|
big1991, стало ещё меньше понятно....
Если это метод-обработчик, то при чём здесь очередь? Произошло событие, вызвался обработчик в том же потоке что и событие, получил результат и вернул его. Если в это время произойдёт другое событие, то этот же обработчик будет в потоке другого события обрабатывать другие данные. Обработчик это метод и какая разница сколько событий его одновременно вызывают?
0
|
|
|
Модератор
|
|||||||
| 16.08.2021, 21:58 | |||||||
|
big1991, по интерфейсу Форума:
1
|
|||||||
|
Уважайте чужое время
75 / 23 / 8
Регистрация: 01.02.2013
Сообщений: 191
|
|||||||
| 17.08.2021, 00:11 [ТС] | |||||||
|
Не по теме: Элд Хасп, спасибо за пояснение по обращению, всё думал, как же это делается. Просто я использую этот объект в методе, который вызывает этот обработчик, поэтому так описал этот момент в коде. Если я создам на каждый вызов по обработчику, то потеряю приблизительно в 300-400 раз больше времени, чем используя один и тот же для разных вызовов (работа заранее созданного обработчика для одного вызова в среднем занимает ~1мс, а создать новый — 300-400мс), поэтому пользуюсь одним, созданным при инициализации программы и записанном в статическом свойстве, к которому обращаются все вызовы в коде. Ускорение на пару порядков таким образом получил, но иногда происходит эксепшен о том, что к обработчику обратилось больше вызовов, чем он может потянуть одновременно. Добавлено через 1 час 8 минут Пока обошёлся костылём:
В перспективе уйду от статического объекта обработчика (используемый в функции ProcessingFunction), к набору объектов, а эти методы порефакторю до чего-то более адекватного, но осознаю, что хоть оно и работает, но это не более, чем костыль =(
0
|
|||||||
|
Модератор
|
|||
| 17.08.2021, 09:18 | |||
|
Вызывается асинхронно метод CallOfProcessing?Он создаёт новый QueueEntry добавляет его в BlockingCollectionQueue.Потом в цикле получает этот же QueueEntry и ожидает пока _guid не перестанет быть равным Guid.Empty.Метод ProcessQueue удаляет objToRecognizeNext из коллекции и после удаления записывает его в ResultsList.Но абсолютно непонятно откуда берётся этот objToRecognizeNext и что за флаг IsCancelled .Так же непонятно как эти методы вызываются. Информация очень скупая и сделать по ней какие-либо выводы просто невозможно. Пусть обработчик объект. Но в каждом вызове вы обращаетесь к его методу. Это не означает, что нужно для каждого вызова создавать новый объект обработчика. Ничто не мешает асинхронно юзать его методы в любом количестве. Покажите как вы реализуете эти вызовы в случае если для каждого надо создавать новый объект-обработчик и для случая использования единного. Код сократите до существенного только для обсуждаемого вопроса.
0
|
|||
|
Уважайте чужое время
75 / 23 / 8
Регистрация: 01.02.2013
Сообщений: 191
|
|||||||||||||||||||||||
| 17.08.2021, 11:46 [ТС] | |||||||||||||||||||||||
|
Насчет комментариев к коду - мой косяк, согласен. Объект сам налагает ограничение на один вызов своих методов одновременно, т.к. это не просто метод на 5 строчек кода, а немаленькая библиотека на 400кб оптимизированного кода. (написана не мной). В коде не описан флаг
Я бы внёс ясность, если бы сделал класс нестатическим, либо если бы добавил объект-обработчик, полагаю: Расширил код до обсуждаемого объёма с комментариями. Если вставить его в IDE, то должно быть понятно.
0
|
|||||||||||||||||||||||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|||||||||||
| 17.08.2021, 13:31 | |||||||||||
Сообщение было отмечено big1991 как решение
Решение
big1991, по-моему, вам нужна асинхронная очередь с TaskCompletionSource.
Как-то так:
Каждая введенная в консоль строка будет отправлена на "обработку" как Arg. Ввод пустой строки отменяет все текущие задачи.
2
|
|||||||||||
|
Модератор
|
||
| 17.08.2021, 13:34 | ||
|
Если правильно понял, то "бутылочное горлышко" это метод SomeProcess который может вызываться одновременно только один?Для следующего вызова надо подождать завершения предыдущего вызо?
0
|
||
|
Уважайте чужое время
75 / 23 / 8
Регистрация: 01.02.2013
Сообщений: 191
|
|||
| 17.08.2021, 14:00 [ТС] | |||
|
Добавлено через 18 минут Сегодня-завтра попробую внедрить. Но здесь вроде бы "из коробки" параллелизм доступен только для одного инстанса обработчика. А если я хочу, чтобы при таком же подходе при "переполнении" определённого порога наполненности очереди (пусть те же 100 или меньше), он не в ожидание вставал, а асинхронно создавался новый инстанс и работал уже параллельно первому, то мне нужно будет: 1. Переделать поле обработчика на список. 2. Добавить механизм, который: 2.1. Добавляет и убирает обработчики по мере необходимости 2.2. Отмечает, когда обработчик свободен (возможно записывает рядом с ним в какой-то коллекции значение флага по факту Completion последнего обработанного элемента или типа того... Пока этого не понял, как попробую в коде — отпишусь, как сделал. 2.3. Ну и чтобы выбирал, какой из обработчиков запустить к текущему элементу. 3. Устанавливать MaxDegreeOfParallelism в значение .Count списка обработчиков. Выглядит просто. Спасибо огромное, kolorotur! Не по теме:
Кликните здесь для просмотра всего текста
Осталось эту асинхронность запилить в мой повсеместно синхронный код, ничего не сломав в логике.
Разумеется асинхронность в программе присутствует, но намного дальше кода, вызывающего описанные выше участки, они выполняются последовательно, но каждый в своём потоке. Но это уже к теме не относится.
0
|
|||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||||
| 17.08.2021, 14:11 | ||||
Сообщение было отмечено big1991 как решение
РешениеВам же надо было прицепить именно асинхронные вызовы к синхронной обработке.
1
|
||||
|
Модератор
|
|||||||
| 17.08.2021, 15:31 | |||||||
Сообщение было отмечено big1991 как решение
Решение
1
|
|||||||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||
| 17.08.2021, 15:51 | ||
|
Это реализация "очереди", где потоки из пула используются вместо массива элементов, только на каждый элемент выделяется 1 МБ памяти вместо пары десяткой байтов на ссылки и целый поток, который тут же блокируется вместо того, чтобы заниматься полезной работой. Судя по имени параметра objToRecognizeNext можно предположить, что у автора может быть какая-нибудь обработка изображений. Несложно представить хаос, который начнется в пуле потоков, если пользователь скормит программе папочку с базой фотографий, на каждую из которых будет вызван SomeProcessAsync. Плюс очередь выполнения не гарантируется (что не так страшно, если автору не нужно именно последовательное выполнение).
1
|
||
|
Модератор
|
||||
| 17.08.2021, 16:14 | ||||
|
Но исходя из условий задачи, не думаю, что стоит заморачиваться: Этот момент я специально у TC уточнял.
0
|
||||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|||
| 17.08.2021, 16:19 | |||
|
Правда, тогда непонятна вот эта ситуация:
0
|
|||
|
Модератор
|
||
| 17.08.2021, 16:27 | ||
|
Пытался выяснить, но как-то ясного ответа не получил. Так как если возможна такая большая очерёдность, то нужно создавать несколько экземпляров объектов-обработчиков и "дирижировать" ими. Иначе, как не делай, будут возможны лаги. Добавлено через 1 минуту big1991, АУ !!! Треба большей ясности по вероятному количеству одновременных запросов и допускам по лагам в связи с этим.
0
|
||
|
Уважайте чужое время
75 / 23 / 8
Регистрация: 01.02.2013
Сообщений: 191
|
||||||||
| 17.08.2021, 16:49 [ТС] | ||||||||
|
И у меня с асинхронными и параллельными операциями пока что всё плохо, так что спасибо за "пинок"! Всем спасибо, для меня — решено. Добавлено через 11 минут Наплыв запросов происходит не 100% времени работы, но это систематическая обычная ситуация даже при средней нагрузке приложения. Дальше будет больше, и соответственно начнется переполнение очереди и понадобится асинхронная параллельная обработка разными обработчиками. Допускаю, что сейчас проблема ещё и в архитектуре самого приложения, но эти грабли пока что вне моего поля зрения =) Добавлено через 10 минут В зависимости от настроек и загруженности приложения, частота будет от 300 запросов (т.е. и 1 обработчик справится с блокировками) в секунду и до нескольких тысяч, тут уже возможны задержки, но если наплодить обработчиков на каждый поток, как посоветовал уважаемый kolorotur, то проблем не станет. По лагам: не существенно. В зависимости от того, насколько хорошо получится разобраться с другими модулями, может быть удастся снизить частоту запросов и проблемы вообще не станет. Это узкое место только в данный момент. Так что ещё раз спасибо!
0
|
||||||||
| 17.08.2021, 16:49 | |
|
Помогаю со студенческими работами здесь
18
Вывод на экран результата вызова ls После вызова второго запроса, запросы начинаются повторяться по очереди Зачем нужно преобразование при присваивании указателю результата вызова malloc? Получение коллекции из ассинхронного вызова Получение телефонного номера входящего вызова в ОС windows phone 7 Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
|
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений.
9TO2GP2bpX4
a42b81fb172ffc12ca589c7898261ccb/
https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/
Слева синяя линия -. . .
|
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. .
Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
|
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога
Финальные проекты на Си и на C++:
finish-text-sdl3-c. zip
finish-text-sdl3-cpp. zip
|
|
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
|
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo
Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло.
Но на выплатах по больничным это. . .
|
Контроль уникальности заводского номера
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере нетипового документа выдачи шин для спецтехники с табличной частью, разработанного в конфигурации КА2. Данные берутся из. . .
|
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y
Z4Tv2zpXVVo
https:/ / github. com/ shumilovas/ med2. git
|