Cosmos.Coroutines 1.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Cosmos.Coroutines --version 1.0.0
NuGet\Install-Package Cosmos.Coroutines -Version 1.0.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Cosmos.Coroutines" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Cosmos.Coroutines --version 1.0.0
#r "nuget: Cosmos.Coroutines, 1.0.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Cosmos.Coroutines as a Cake Addin
#addin nuget:?package=Cosmos.Coroutines&version=1.0.0

// Install Cosmos.Coroutines as a Cake Tool
#tool nuget:?package=Cosmos.Coroutines&version=1.0.0

cosmos-coroutines

A simple, non-preemptive coroutine scheduler that allows for cooperative multitasking within Cosmos kernels.

This project is mainly to demonstrate the ability to use the C# iterator feature to achieve coopertive multi-tasking; in itself, it's very simplistic - the whole implementation is contained in only 6 files.

Limitations

Cosmos.Coroutines has the following limitations:

  • non-preemptive; you need to do a yield return to hand back control over to the coroutine scheduler
  • basic round-robin; no prority system
  • CPU halting in many parts of Cosmos will also halt the coroutine pool scheduler

Other than this, it can act as a normal cooperative kernel task scheduler.

Usage

After importing the library to your project, you will be able to include a using Cosmos.System.Coroutines directive. This will result in the following classes being available to you:

  • Coroutine - represents a single coroutine. A coroutine can belong to only one CoroutinePool.
  • CoroutinePool - manages multiple coroutines and schedules stepping through iterations (yields). A global CoroutinePool is allocated on startup and can be accessed using CoroutinePool.Main. This pool will not affect the execution of the OS in any way until StartPool will be called.
  • CoroutineControlPoint - the object returned by IEnumerators that the Coroutine constructor accepts. Specifies whether the coroutine should be ticked at a given time.
  • WaitFor - a CoroutineControlPoint that waits for the specified amount of nanoseconds.
  • WaitUntil - a CoroutineControlPoint that waits until a condition is met.
  • WaitIndefinetly - a CoroutineControlPoint that halts the coroutine until it's explicitly un-halted through said control point.

To use the main CoroutinePool, simply do:

CoroutinePool.Main.StartPool();

To create a coroutine:

var coroutine = new Coroutine(MyCoroutine5());
coroutine.Start(); // will run the coroutine on the main pool; to run it in another, use CoroutinePool.AddCoroutine

// ...

IEnumerator<CoroutineControlPoint> MyCoroutine1()
{
    while(true) {
        Console.WriteLine("This prints every second.");
        yield return WaitFor.Seconds(1);
    }
}

You can start as many coroutines as you want, however please note that with more coroutines, the slower the operating system gets.

Warning<br> A coroutine is not the same as a traditional C# thread; and you should not mistake the two. A C# thread is preempted; that is, if the thread will encounter, for example, an infinite loop, the kernel will still continue to execute, as the thread will be automatically switched from (preempted) after a time quantum. A coroutine relies on the method to volountarily give back control to the pool; if a software bug appears that would make the coroutine refrain from giving back control over to the pool, the kernel would halt.

Creating a "main" function

Sometimes, after performing a cycle over all coroutines, you want to execute kernel code to perform e.g. maintanance tasks. This can be easily achieved using the CoroutinePool.OnCoroutineCycle event:

CoroutinePool.OnCoroutineCycle += Main;
CoroutinePool.Main.StartPool();

// ...

void Main() {
    // everything in this method will be executed after a pool cycle
}

As this is a regular C# event, you can have as many handlers as you want.

Coroutines and memory management

CoroutinePools can be set to automatically collect all unused objects on the heap after all coroutines finish a single cycle. This is enabled by default for the main pool, but disabled for user-created pools. It's strongly recommended to enable periodic heap collection if you're running the pool on your main thread (most likely the case with Cosmos).

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.1 304 9/7/2023
1.0.0 303 1/5/2023