177 / 32 / 17
Регистрация: 02.02.2014
Сообщений: 359
|
|
1 | |
Собственные задачи08.10.2016, 22:30. Показов 728. Ответов 4
Метки нет (Все метки)
Привет всем!
Столкнулся с тем, что в некоторых ситуациях Task.Run не сразу запускает задачу, а ставит на планирование. Первый вопрос - можно ли этого избежать? Пока ответа я не нашел, поэтому, а так же по ряду других ограничений, которые есть в оригинальной TaskModel, сделал свой пул потоков, работающий со своими задачами. Сейчас делаю await (т.е. чтобы к моим задачам тоже можно было делать await). Создал awaiter, унаследовал интерфейс ICriticalNotifyCompletion, реализовал, всё как положено. Сделал сохранение контекста синхронизации, если таковой был. Если я правильно понял, при срабатывании await у задачи вызывается GetAwaiter, который возвращает экземпляр этого самого Awaiter. У этого Awaiter вызывается метод OnCompleted, этому методу передается Continuation - делегат, оборачивающий весь код, который идет после await, и я должен его выполнить после того, как моя задача отработает. Я сохраняю этот делегат в задаче, и она, после выполнения, запускает этот Continuation. При тестировании выяснилось, что код после await срабатывает не всегда. Происходит это, как я выяснил, потому, что OnCompleted у аваитера в некоторые моменты вызывается уже после того, как задача выполнилась, соответственно, Continuation делать она уже не будет. Понятное дело - это же параллельные потоки. Теперь вопрос - как сделать так, чтобы OnCompleted вызывалось до старта задачи? Как узнать, что вот эта задача должна сначала дождаться вызова метода OnCompleted с передачей делегата? Или как вообще определить, что задача, хоти выполнила свой основной код до конца, должна дождаться еще и continuation-кода? Или как вообще это делают? Понимаю, что дич сложная, рассчитываю на то, что может кто-то тоже писал TaskModel, и как-то решил данную проблему. Заранее спасибо. PS. Да, я знаю про рефлектор, сейчас пока безуспешно пытаюсь понять как это делает оригинальная TaskModel.
0
|
08.10.2016, 22:30 | |
Ответы с готовыми решениями:
4
Собственные значения и собственные векторы матрицы Собственные теги в OpenXML Можно ли комментировать собственные функции Собственные значения симметричной матрицы |
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
|
||||||
04.11.2016, 00:55 | 2 | |||||
Задержка может быть вызвана тем, что пул потоков "неохотно"(с задержкой где-то 0.5c) создаёт новые потоки, если количество уже созданных потоков достигло или превышает количества ядер процессора. Можно исправить методом
2
|
17793 / 12944 / 3381
Регистрация: 17.09.2011
Сообщений: 21,227
|
||||||
04.11.2016, 13:49 | 4 | |||||
Подозреваю, что где-то в коде GetAwaiter вы запускаете задачу в отдельном потоке, по окончании работы которой пытаетесь вызвать делегат, который к тому времени, возможно, еще не был передан через OnCompleted.
При работе в асинхронной среде лучше не предполагать, что какое-то действие будет выполнено строго до или после другого действия, вместо этого лучше лишний раз обложиться проверками. Если вы пишете свой Awaiter, то у него должен быть метод GetResult и свойство IsCompleted, которое вы можете использовать и в своих целях. Если есть вероятность того, что параллельная задача выполнится до вызова OnCompleted, то всего-навсего добавьте проверку в оба места и вызывайте делегат в соответствующем. Как-то так:
Лучше всего — в реализации геттера и сеттера самого свойства, т.к. внешний код тоже будет к нему обращаться.
1
|
177 / 32 / 17
Регистрация: 02.02.2014
Сообщений: 359
|
|
05.11.2016, 18:42 [ТС] | 5 |
Огромное спасибо! Так и было - OnCompleted срабатывал позже завершения задачи, и к моменту, когда задача завершалась, continuation еще не было передано. Теперь всё заработало
PS. ThreadPool.SetMinThreads на всякий тоже поставил побольше.
0
|
05.11.2016, 18:42 | |
05.11.2016, 18:42 | |
Помогаю со студенческими работами здесь
5
Как удалить из текста все имена собственные? Когда или в каких случая нужно создавать собственные исключения? Как с помощью регулярных выражений выбрать только все имена собственные? Нужен пример использования вместо значений словаря — свои собственные классы Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи | |||||
Как проводить научные вычисления на Python
InfoMaster 15.01.2025
Python стал одним из наиболее востребованных языков программирования в области научных вычислений благодаря своей простоте, гибкости и обширной экосистеме специализированных библиотек. Научные. . .
|
Создание игры типа Minecraft на PyGame/Python: пошаговое руководство
InfoMaster 15.01.2025
В данном руководстве мы рассмотрим процесс создания игры в стиле Minecraft с использованием библиотеки PyGame на языке программирования Python. Этот проект идеально подходит как для начинающих. . .
|
Как создать свою первую игру в стиле Doom на Unreal Engine
InfoMaster 15.01.2025
Разработка шутера от первого лица в стиле классического Doom представляет собой увлекательное путешествие в мир игрового программирования, где сочетаются творческий подход и технические навыки. . . .
|
Параллельное программирование: основные технологии и принципы
InfoMaster 15.01.2025
Введение в параллельное программирование
Параллельное программирование представляет собой фундаментальный подход к разработке программного обеспечения, который позволяет одновременно выполнять. . .
|
Как написать микросервис на C# с Kafka, MediatR, Redis и GitLab CI/CD
InfoMaster 15.01.2025
В современной разработке программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот подход позволяет разделить сложную систему. . .
|
Что такое CQRS и как это реализовать на C# с MediatR
InfoMaster 15.01.2025
Концепция CQRS и её роль в современной разработке
В современном мире разработки программного обеспечения архитектурные паттерны играют ключевую роль в создании масштабируемых и поддерживаемых. . .
|
Как настроить CI/CD с Azure DevOps
InfoMaster 15.01.2025
CI/ CD, или непрерывная интеграция и непрерывное развертывание, представляет собой современный подход к разработке программного обеспечения, который позволяет автоматизировать и оптимизировать процесс. . .
|
Как настроить CI/CD с помощью Jenkins
InfoMaster 15.01.2025
Введение в CI/ CD и Jenkins
В современной разработке программного обеспечения непрерывная интеграция (CI) и непрерывная доставка (CD) стали неотъемлемыми элементами процесса создания качественных. . .
|
Как написать микросервис на Go/Golang с Kafka, REST и GitHub CI/CD
InfoMaster 14.01.2025
Определение микросервиса, преимущества использования Go/ Golang
Микросервис – это архитектурный подход к разработке программного обеспечения, при котором приложение состоит из небольших, независимо. . .
|
Как написать микросервис с нуля на C# с RabbitMQ, CQRS, Swagger и CI/CD
InfoMaster 14.01.2025
В современном мире разработки программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот архитектурный подход предполагает. . .
|
Как создать интернет-магазин на PHP и JavaScript
InfoMaster 14.01.2025
В современном мире электронная коммерция стала неотъемлемой частью бизнеса. Создание собственного интернет-магазина открывает широкие возможности для предпринимателей, позволяя достичь большей. . .
|
Как написать Тетрис на Ассемблере
InfoMaster 14.01.2025
Тетрис – одна из самых узнаваемых и популярных компьютерных игр, созданная в 1984 году советским программистом Алексеем Пажитновым. За прошедшие десятилетия она завоевала симпатии миллионы людей по. . .
|