У нас есть высокопроизводительная многозадачная программа, работающая почти на реальном времени на C #. Эта производительность была достигнута, в основном, за счет совместной реализации многозадачности с помощью собственного планировщика. Это часто называют микропотоками. В этой системе все задачи связываются с другими задачами через очереди.
Конкретная проблема, которую мы имеем, кажется, может быть решена только через продолжения первого класса, которые C # не поддерживает.
В частности, проблема возникает в 2 случаях, связанных с очередями. Всякий раз, когда какая-либо конкретная задача выполняет некоторую работу, прежде чем поместить элемент в очередь. Что, если очередь заполнена?
И наоборот, другая задача может выполнить некоторую работу, а затем потребуется удалить элемент из очереди. Что если эта очередь пуста?
Мы решили эту проблему в 90% случаев, связав очереди с задачами, чтобы избежать вызова задач, если какая-либо из их исходящих очередей заполнена или входящая очередь пуста.
Кроме того, некоторые задачи были преобразованы в конечные автоматы, чтобы они могли обрабатывать, если очередь заполнена / пуста, и продолжить без ожидания.
Реальная проблема возникает в нескольких крайних случаях, когда нецелесообразно принимать какое-либо из этих решений. Идея в этом сценарии состояла бы в том, чтобы сохранить состояние стека в точке и переключиться на другую задачу, чтобы он мог выполнить работу и впоследствии повторить задачу ожидания, когда сможет продолжить.
В прошлом мы пытались вернуть задачу ожидания обратно в расписание (рекурсивно), чтобы позволить другим задачам и позже повторить задачу ожидания. Однако это привело к слишком большому количеству «тупиковых» ситуаций.
Был где-то пример пользовательского хоста CLR, который заставлял потоки .NET фактически работать как "волокна", которые по существу позволяют переключать состояние стека между потоками. Но сейчас я не могу найти пример кода для этого. Кроме того, кажется, что для того, чтобы сделать это правильно, потребуются значительные сложности.
Есть ли у кого-нибудь еще творческие идеи, как эффективно переключаться между задачами и избегать вышеуказанных проблем?
Есть ли другие хосты CLR, которые предлагают это, коммерческое или иное? Есть ли какая-нибудь нативная библиотека дополнений, которая может предложить какую-то форму продолжений для C #?