Loading repository data…
Loading repository data…
styropyr0 / repository
This library provides a simple and efficient way to manage asynchronous code in .NET applications, inspired by Kotlin's coroutines. It supports custom dispatchers for flexible threading, and integrates seamlessly with existing Task-based code.
This coroutine library offers an intuitive and flexible approach to asynchronous programming in C#, inspired by Kotlin's coroutine system. It simplifies concurrency by abstracting away the complexity of managing threads and execution contexts. This library provides a powerful model for suspending, resuming, and managing coroutines while ensuring clean and maintainable code. With advanced dispatchers, coroutine scopes, timeouts, and more, it is a comprehensive solution for handling asynchronous workflows in your C# applications.
DefaultContext, IOContext, MainContext, and UnconfinedContext.CoroutineScope and CoroutineScopeWithCancellation.GlobalScope for long-lived coroutines that are managed application-wide.CoroutineTimeout.CoroutineBuilder.Suspend functions to pause execution and resume later.git clone https://github.com/styropyr0/Coroutines
.dll and reference it in your project.Alternatively, if you prefer to install via .NET CLI or Package Manager:
dotnet add package CoroutinesForCS --version <version>
NuGet\Install-Package CoroutinesForCS -Version <version>
Dispatchers are central to the coroutine library as they define the execution context for coroutines. Each dispatcher determines where and how coroutines are executed, whether on the default thread pool, a dedicated I/O thread, the main thread, or on any available thread.
DefaultContextTask ExecuteAsync(Func<Task> task, CancellationToken cancellationToken): Executes a coroutine asynchronously.Task<T> ExecuteAsync<T>(Func<Task<T>> task, CancellationToken cancellationToken): Executes a coroutine asynchronously with a result.DefaultContext.IOContextTask ExecuteAsync(Func<Task> task, CancellationToken cancellationToken): Executes an I/O-bound task asynchronously.Task<T> ExecuteAsync<T>(Func<Task<T>> task, CancellationToken cancellationToken): Executes an I/O-bound task asynchronously with a result.IOContext.MainContextSynchronizationContext. This is useful for UI-related tasks that need to interact with the UI thread.Task ExecuteAsync(Func<Task> task, CancellationToken cancellationToken): Executes a coroutine on the main thread asynchronously.Task<T> ExecuteAsync<T>(Func<Task<T>> task, CancellationToken cancellationToken): Executes a coroutine on the main thread asynchronously with a result.MainContext.UnconfinedContextTask ExecuteAsync(Func<Task> task, CancellationToken cancellationToken): Executes a coroutine without a fixed execution thread.Task<T> ExecuteAsync<T>(Func<Task<T>> task, CancellationToken cancellationToken): Executes a coroutine without a fixed execution thread, returning a result.UnconfinedContext.// Creating and using Dispatchers
// DefaultContext
var defaultDispatcher = Dispatcher.Default;
await defaultDispatcher.ExecuteAsync(async () =>
{
Console.WriteLine("Running on the default context");
});
// IOContext
var ioDispatcher = Dispatcher.IO;
await ioDispatcher.ExecuteAsync(async () =>
{
Console.WriteLine("Running I/O bound task");
});
// MainContext
var mainDispatcher = Dispatcher.Main;
await mainDispatcher.ExecuteAsync(async () =>
{
Console.WriteLine("Running on the main thread for UI operations");
});
// UnconfinedContext
var unconfinedDispatcher = Dispatcher.Unconfined;
await unconfinedDispatcher.ExecuteAsync(async () =>
{
Console.WriteLine("Running in an unconfined context");
});
The CoroutineScope class is designed to manage and coordinate the execution of coroutines within a specific context or dispatcher. It allows you to launch multiple coroutines, handle cancellations, and wait for their completion in an organized manner.
CoroutineScope(Dispatcher context)CoroutineScope class with a specified dispatcher. The dispatcher defines where the coroutines will run (e.g., on the main thread, I/O thread, etc.).Launch (Action)
Launches a coroutine that takes no parameters and returns no value.
public async Task Launch(Action coroutine, Dispatcher dispatcher = null)
Launch (Func)
Launches a coroutine that takes a value and returns that value.
public async Task Launch<T>(Func<T> coroutine, Dispatcher dispatcher = null)
Launch (Func)
Launches a coroutine that returns a Task and waits for its completion.
public async Task Launch(Func<Task> coroutine, Dispatcher dispatcher = null)
Combine (Action)
Combines multiple coroutines that take no parameters and run them in parallel.
public async Task Combine(IEnumerable<Action> coroutines, Dispatcher dispatcher = null)
Combine (Func)
Combines multiple coroutines that take a value and run them in parallel.
public async Task Combine<T>(IEnumerable<Func<T>> coroutines, Dispatcher dispatcher = null)
Combine (Func)
Combines multiple coroutines that return a Task and runs them in parallel.
public async Task Combine(IEnumerable<Func<Task>> coroutines, Dispatcher dispatcher = null)
CombineFirst (Action)
Combines multiple coroutines and executes the first one to complete.
public async Task CombineFirst(IEnumerable<Action> coroutines, Dispatcher dispatcher = null)
CombineFirst (Func)
Combines multiple coroutines that return a Task and executes the first one to complete.
public async Task CombineFirst(IEnumerable<Func<Task>> coroutines, Dispatcher dispatcher = null)
WaitAllAsync
Waits for all coroutines to complete in the current scope.
public async Task WaitAllAsync()
Cancel
Cancels all coroutines in the current scope.
public void Cancel()
CoroutineScope:// Initialize the CoroutineScope with a specific dispatcher
var scope = new CoroutineScope(Dispatcher.IO);
// Launch a coroutine that takes no parameters
await scope.Launch(() =>
{
Console.WriteLine("Running a simple coroutine.");
});
// Launch a coroutine that returns a result
await scope.Launch(() =>
{
return 42; // Example returning a result
});
// Combine multiple coroutines to run in parallel
await scope.Combine(new List<Action>
{
() => Console.WriteLine("First parallel task"),
() => Console.WriteLine("Second parallel task")
});
// Wait for all tasks in the scope to complete
await scope.WaitAllAsync();
// Cancel all running coroutines
scope.Cancel();
// Dispose of the scope when done
await scope.DisposeAsync();
GlobalScope provides global access to coroutine scopes and utilities for launching, combining, and managing coroutines. It acts as a container for coroutines, handling their execution across different dispatcher contexts. This section explains how to use GlobalScope to manage coroutine tasks globally.
Launch No Parameters:
public static async Task Launch(Action coroutine, Dispatcher dispatcher = null, CancellationToken cancellationToken = default)
Launches a coroutine with no parameters (an Action) in the given dispatcher context. If no dispatcher is provided, the default dispatcher is used.
Launch With Return Value:
public static async Task Launch<T>(Func<T> coroutine, Dispatcher dispatcher = null, CancellationToken cancellationToken = default)
Launches a coroutine that returns a value of type T.
Launch Task Coroutine:
public static async Task Launch(Func<Task> coroutine, Dispatcher dispatcher = null, CancellationToken cancellationToken = default)
Launches a coroutine that returns a Task and waits for its completion.
Combine No Parameters:
public static async Task Combine(IEnumerable<Action> coroutines, Dispatcher dispatcher = null, CancellationToken cancellationToken = default)
Combines multiple Action coroutines and runs them in parallel.
Combine With Return Values:
public static async Task Combine<T>(IEnumerable<Func<T>> coroutines, Dispatcher dispatcher = null, CancellationToken cancellationToken = default)
Combines multiple coroutines that return values of type T and runs them in parallel.
Combine Task Coroutines:
public static async Task Combine(IEnumerable<Func<Task>> coroutines, Dispatcher dispatcher = null, CancellationToken cancellationToken = default)
Combines multiple Task-returning coroutines and runs them in parallel.
Combine First to Complete:
public static async Task CombineFirst(IEnumerable<Action> coroutines, Dispatcher dispatcher = null, CancellationToken cancellationToken = default)
Combines multiple Action coroutines and executes the first one to complete.
Combine Task First to Complete:
public static async Task CombineFirst(IEnumerable<Func<Task>> coroutines, Dispatcher dispatcher = null, CancellationToken cancellationToken = default)
Combines multiple Task-returning coroutines and executes the first one to complete.
DisposeAsync
Disposes of the CoroutineScope, cancelling any ongoing coroutines and waiting for them to finish.
public async ValueTask DisposeAsync()
GetTasks
Gets the collection of tasks that are still running and not cancelled.
public IEnumerable<Task> GetTasks(CancellationToken cancellationToken)