GDTask 0.0.3
See the version list below for details.
dotnet add package GDTask --version 0.0.3
NuGet\Install-Package GDTask -Version 0.0.3
<PackageReference Include="GDTask" Version="0.0.3" />
<PackageVersion Include="GDTask" Version="0.0.3" />
<PackageReference Include="GDTask" />
paket add GDTask --version 0.0.3
#r "nuget: GDTask, 0.0.3"
#:package GDTask@0.0.3
#addin nuget:?package=GDTask&version=0.0.3
#tool nuget:?package=GDTask&version=0.0.3
GDTask.Nuget
- Ported and Tested in Godot 4.2 with .Net module.
- This is the Nuget Package version based on code from:
Abstract
Clarification: Contents in the abstract section is mostly migrated from the Cysharp's UniTask library for Unity
Efficient allocation free async/await integration for Godot
- Struct based GDTask<T> and custom AsyncMethodBuilder to achieve zero allocation.
- Provides awaitable functionality for certain Engine event functions.
- Runs completely on Godot PlayerLoop so doesn't use threads.
- Highly compatible behaviour with Task/ValueTask/IValueTaskSource.
GDTask Under the hood
- Based on the task-like custom async method builder feature. of C# 7.0, GDTask does not use Threads, SynchronizationContext, or ExecutionContext. Instead, it dispatches the asynchronous tasks onto a standalone singleton node GDTaskPlayerLoopRunner, which results in better performance, and lower allocation.
Installation via Nuget
For .Net CLI
dotnet add package GDTask
For Package Manager Console:
NuGet\Install-Package GDTask
Basic API usage
For more detailed usage, see Unit Tests.
using GodotTasks.Tasks;
// Use GDTaskVoid if this task is only used with ApiUsage().Forget();
public async GDTask ApiUsage()
{
// Delay the execution after frame(s).
await GDTask.DelayFrame(100);
// Delay the execution after delayTimeSpan.
await GDTask.Delay(TimeSpan.FromSeconds(10), DelayType.Realtime);
// Delay the execution until the next Process.
await GDTask.Yield(PlayerLoopTiming.Process);
// Delay the execution until the next PhysicsProcess.
await GDTask.WaitForPhysicsProcess();
// Creates a task that will complete at the next provided PlayerLoopTiming when the supplied predicate evaluates to true
await GDTask.WaitUntil(() => Time.GetTimeDictFromSystem()["minute"].AsInt32() % 2 == 0);
// Creates a task that will complete at the next provided PlayerLoopTiming when the provided monitorFunction returns a different value.
await GDTask.WaitUntilValueChanged(Time.Singleton, timeInstance => timeInstance.GetTimeDictFromSystem()["minute"]);
// Creates an awaitable that asynchronously yields to ThreadPool when awaited.
await GDTask.SwitchToThreadPool();
/* Threaded work */
// Creates an awaitable that asynchronously yields back to the next Process from the main thread when awaited.
await GDTask.SwitchToMainThread();
/* Main thread work */
await GDTask.NextFrame();
// Creates a continuation that executes when the target GDTask completes.
int taskResult = await GDTask.Delay(10).ContinueWith(() => 5);
GDTask<int> task1 = GDTask.Delay(10).ContinueWith(() => 5);
GDTask<string> task2 = GDTask.Delay(20).ContinueWith(() => "Task Result");
GDTask<bool> task3 = GDTask.Delay(30).ContinueWith(() => true);
// Creates a task that will complete when all of the supplied tasks have completed.
var (task1Result, task2Result, task3Result) = await GDTask.WhenAll(task1, task2, task3);
try
{
// Creates a GDTask that has completed with the specified exception.
await GDTask.FromException(new ExpectedException());
}
catch (ExpectedException) { }
try
{
// Creates a GDTask that has completed due to cancellation with the specified cancellation token.
await GDTask.FromCanceled(CancellationToken.None);
}
catch (TaskCanceledException) { }
try
{
var source = new CancellationTokenSource();
source.CancelAfter(100);
// Creates a task that never completes, with specified CancellationToken.
await GDTask.Never(source.Token);
}
catch (TaskCanceledException) { }
// Queues the specified work to run on the ThreadPool and returns a GDTask handle for that work.
await GDTask.RunOnThreadPool(
() => GD.Print(Environment.CurrentManagedThreadId.ToString()),
configureAwait: true,
cancellationToken: CancellationToken.None
);
// Create a GDTask that wraps around this task.
await Task.Delay(5).AsGDTask(useCurrentSynchronizationContext: true);
// Associate a time out to the current GDTask.
await GDTask.Never(CancellationToken.None).Timeout(TimeSpan.FromMilliseconds(5));
var node = new Node();
((SceneTree)Engine.GetMainLoop()).Root.CallDeferred(Node.MethodName.AddChild, node);
// Creates a task that will complete when the _EnterTree() is called.
await node.OnEnterTreeAsync();
// Creates a task that will complete when the _Ready() is called.
await node.OnReadyAsync();
// Gets an instance of IAsyncProcessHandler for making repeatedly calls on OnProcessAsync().
var processTrigger = node.GetAsyncProcessTrigger();
// Creates a task that will complete when the next _Process(double) is called.
await processTrigger.OnProcessAsync();
await processTrigger.OnProcessAsync();
await processTrigger.OnProcessAsync();
await processTrigger.OnProcessAsync();
// Gets an instance of IAsyncPhysicsProcessHandler for making repeatedly calls on OnPhysicsProcessAsync().
var physicsProcessTrigger = node.GetAsyncPhysicsProcessTrigger();
await physicsProcessTrigger.OnPhysicsProcessAsync();
await physicsProcessTrigger.OnPhysicsProcessAsync();
await physicsProcessTrigger.OnPhysicsProcessAsync();
await physicsProcessTrigger.OnPhysicsProcessAsync();
node.QueueFree();
// Creates a task that will complete when the Node is receiving NotificationPredelete.
await node.OnPredeleteAsync();
}
Compare with Standard .Net Task API
Clarification: Contents in the compare section is mostly migrated from the Cysharp's UniTask library for Unity
Same as the Standard .Net Task APIs, CancellationToken and CancellationTokenSource are widely used by the GDTask APIs as well.<br>
Otherwise, the following table shows the GDTask APIs provided that are meant to replace the usage of standard .Net Task APIs.
| .NET Type | GDTask Type |
|---|---|
Task/ValueTask |
GDTask |
Task<T>/ValueTask<T> |
GDTask<T> |
async void |
async GDTaskVoid |
+= async () => { } |
GDTask.Void, GDTask.Action |
| --- | GDTaskCompletionSource |
TaskCompletionSource<T> |
GDTaskCompletionSource<T>/AutoResetGDTaskCompletionSource<T> |
ManualResetValueTaskSourceCore<T> |
GDTaskCompletionSourceCore<T> |
IValueTaskSource |
IGDTaskSource |
IValueTaskSource<T> |
IGDTaskSource<T> |
ValueTask.IsCompleted |
GDTask.Status.IsCompleted() |
ValueTask<T>.IsCompleted |
GDTask<T>.Status.IsCompleted() |
CancellationToken.Register(UnsafeRegister) |
CancellationToken.RegisterWithoutCaptureExecutionContext |
CancellationTokenSource.CancelAfter |
CancellationTokenSource.CancelAfterSlim |
Task.Delay |
GDTask.Delay |
Task.Yield |
GDTask.Yield |
Task.Run |
GDTask.RunOnThreadPool |
Task.WhenAll |
GDTask.WhenAll |
Task.WhenAny |
GDTask.WhenAny |
Task.CompletedTask |
GDTask.CompletedTask |
Task.FromException |
GDTask.FromException |
Task.FromResult |
GDTask.FromResult |
Task.FromCanceled |
GDTask.FromCanceled |
Task.ContinueWith |
GDTask.ContinueWith |
TaskScheduler.UnobservedTaskException |
GDTaskExceptionHandler.UnobservedTaskException |
| Product | Versions 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 is compatible. 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 is compatible. 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net6.0
- Godot.SourceGenerators (>= 4.0.0)
- GodotSharp (>= 4.0.0)
-
net7.0
- Godot.SourceGenerators (>= 4.0.0)
- GodotSharp (>= 4.0.0)
-
net8.0
- Godot.SourceGenerators (>= 4.0.0)
- GodotSharp (>= 4.0.0)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on GDTask:
| Package | Downloads |
|---|---|
|
BenchmarkDotNetGodot
BenchmarkDotNet.Godot allows developers to easily conduct performance testing and benchmarking within the Godot engine, enabling them to assess the efficiency of their code and identify potential performance bottlenecks. |
|
|
BenchmarkDotNetGodot.GDTask
Package Description |
|
|
GDTask.GlobalCancellation
Adds global cancellations to GDTask.Nuget |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.2 | 40 | 3/10/2026 |
| 2.0.1 | 99 | 3/5/2026 |
| 2.0.0 | 132 | 2/25/2026 |
| 1.7.0 | 572 | 12/20/2025 |
| 1.6.1 | 256 | 10/20/2025 |
| 1.6.0 | 192 | 10/20/2025 |
| 1.5.0 | 276 | 7/1/2025 |
| 1.4.1 | 449 | 4/6/2025 |
| 1.4.0 | 189 | 4/6/2025 |
| 1.3.0 | 478 | 12/4/2024 |
| 1.2.2 | 757 | 3/29/2024 |
| 1.2.1 | 206 | 3/28/2024 |
| 1.2.0 | 209 | 2/27/2024 |
| 1.1.0 | 193 | 2/26/2024 |
| 1.0.0 | 227 | 2/22/2024 |
| 0.0.3 | 806 | 2/2/2024 |
| 0.0.2 | 207 | 1/29/2024 |
| 0.0.1 | 179 | 1/28/2024 |
GDTaskPlayerLoopRunner now uses internal mode when adding to the scene tree.