С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
177 / 32 / 17
Регистрация: 02.02.2014
Сообщений: 359
1

Собственные задачи

08.10.2016, 22:30. Показов 728. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет всем!

Столкнулся с тем, что в некоторых ситуациях 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
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.10.2016, 22:30
Ответы с готовыми решениями:

Собственные значения и собственные векторы матрицы
Задали реализовать нахождения собственных значений и собственных векторов матрицы на языке...

Собственные теги в OpenXML
Есть ли в этом стандарте для docx возможность использовать собственные теги без вывода их в видимое...

Можно ли комментировать собственные функции
к методам стандартных элементов - в коде есть подсказки- после нажатия точки показаны функции и...

Собственные значения симметричной матрицы
Доброго времени суток. Нашел в инете алгоритм с программой на c++, поиск собственных значений...

4
907 / 664 / 318
Регистрация: 23.10.2016
Сообщений: 1,543
04.11.2016, 00:55 2
Цитата Сообщение от VBDUnit Посмотреть сообщение
в некоторых ситуациях Task.Run не сразу запускает задачу, а ставит на планирование
Задержка может быть вызвана тем, что пул потоков "неохотно"(с задержкой где-то 0.5c) создаёт новые потоки, если количество уже созданных потоков достигло или превышает количества ядер процессора. Можно исправить методом
C#
1
ThreadPool.SetMinThreads
2
Эксперт .NET
5546 / 4309 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
04.11.2016, 13:01 3
Цитата Сообщение от VBDUnit Посмотреть сообщение
Или как вообще это делают?
Попробуйте без awiater-а.
Task.Factory.StartNew(()=>{}).ContinueWith(task=>{});

Или можно использовать методы Task.WhenAll(); / Task.WhenAny();
1
Эксперт .NET
17793 / 12944 / 3381
Регистрация: 17.09.2011
Сообщений: 21,227
04.11.2016, 13:49 4
Цитата Сообщение от VBDUnit Посмотреть сообщение
При тестировании выяснилось, что код после await срабатывает не всегда.
Подозреваю, что где-то в коде GetAwaiter вы запускаете задачу в отдельном потоке, по окончании работы которой пытаетесь вызвать делегат, который к тому времени, возможно, еще не был передан через OnCompleted.
При работе в асинхронной среде лучше не предполагать, что какое-то действие будет выполнено строго до или после другого действия, вместо этого лучше лишний раз обложиться проверками.
Если вы пишете свой Awaiter, то у него должен быть метод GetResult и свойство IsCompleted, которое вы можете использовать и в своих целях. Если есть вероятность того, что параллельная задача выполнится до вызова OnCompleted, то всего-навсего добавьте проверку в оба места и вызывайте делегат в соответствующем. Как-то так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class MyAwaiter : INotifyCompletion
{
   private Action continuation;
 
   public bool IsCompleted { get; private set; }
   public object GetResult() => null;
   public void OnCompleted(Action continuation)
   {
      if (IsCompleted)
         continuation(); // Метод вызвался уже после окончания задачи, так что просто вызываем делегат
      else
         this.continuation = continuation; // Сохраняем на потом
   }
   public MyAwaiter GetAwaiter()
   {
      new Thread(RunParallelOperation).Start();
      return this;
   }
 
   private void RunParallelOperation()
   {
      // Чего-нибудь делаем...
 
      IsCompleted = true;
      
      // Делегат уже передали?
      if (continuation != null)
         continuation();
   }
}
Разумеется, если у вас задача выполняется в отдельном потоке, то доступ к IsCompleted надо бы синхронизировать.
Лучше всего — в реализации геттера и сеттера самого свойства, т.к. внешний код тоже будет к нему обращаться.
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
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
05.11.2016, 18:42
Помогаю со студенческими работами здесь

Как удалить из текста все имена собственные?
дан какой-либо текст. написать функцию, которая удалит из теста все имена собственные

Когда или в каких случая нужно создавать собственные исключения?
Добрый день. Во время подготовки к экзамену наткнулся на такой вопрос:"Перехват и генерация...

Как с помощью регулярных выражений выбрать только все имена собственные?
Имеется вот такой текст. Как с помощью регулярных выражений выбрать только все имена...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
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 году советским программистом Алексеем Пажитновым. За прошедшие десятилетия она завоевала симпатии миллионы людей по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru