Table of Contents

Class NwTask

Namespace
Anvil.API
Assembly
NWN.Anvil.dll

Asynchronous tasks and helpers for running NWN APIs in an async context.

public static class NwTask
Inheritance
NwTask
Inherited Members

Examples

/*
 * Example usages of all Async APIs.
 */

using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Anvil.API;
using Anvil.Services;

namespace NWN.Anvil.Samples.API.Async
{
  [ServiceBinding(typeof(NwTaskExamples))]
  public class NwTaskExamples
  {
    public NwTaskExamples()
    {
      _ = DoAsyncStuff();
      _ = CancellationTokenExample();
    }

    private async Task DoAsyncStuff()
    {
      // Do some heavy work on another thread using a standard task, then return to a safe script context.
      await Task.Run(() => Thread.Sleep(1000));
      await NwTask.SwitchToMainThread();

      // Wait for a frame, or a certain amount of frames to pass.
      await NwTask.NextFrame();
      await NwTask.DelayFrame(100);

      // Wait for 30 seconds to pass. (DelayCommand replacement)
      await NwTask.Delay(TimeSpan.FromSeconds(30));

      // Wait for a certain game period to pass.
      await NwTask.Delay(NwTimeSpan.FromRounds(2));
      await NwTask.Delay(NwTimeSpan.FromTurns(3));
      await NwTask.Delay(NwTimeSpan.FromHours(1));

      // Wait for an expression to evaluate to true
      await NwTask.WaitUntil(() => NwModule.Instance.Players.Count() > 5);

      // Wait for a value to change.
      await NwTask.WaitUntilValueChanged(() => NwModule.Instance.Players.Count());

      // Start some tasks.
      Task task1 = Task.Run(() => true); // Executed in the thread pool, you cannot use NWN APIs here.

      Task task2 = Task.Run(async () =>
      {
        // Executed in the thread pool, you cannot use NWN APIs here.
        await Task.Delay(TimeSpan.FromSeconds(5));
        return 20;
      });

      Task task3 = NwTask.Run(async () =>
      {
        // Executed in the server thread, you can use NWN APIs here.
        await NwTask.Delay(NwTimeSpan.FromRounds(5));
        NwModule.Instance.SendMessageToAllDMs("5 rounds elapsed!");
        return 20;
      });

      // ...wait for any of them to complete. The others will still keep running in the background!
      await NwTask.WhenAny(task1, task2, task3);

      // ...wait for all of them to complete.
      await NwTask.WhenAll(task1, task2, task3);
    }

    private async Task CancellationTokenExample()
    {
      // Create a token that will be used to cancel the other tasks.
      CancellationTokenSource tokenSource = new CancellationTokenSource();

      // Start some tasks
      Task task1 = NwTask.WaitUntil(() => NwModule.Instance.Players.Any(), tokenSource.Token);
      Task task2 = NwTask.Delay(TimeSpan.FromSeconds(10), tokenSource.Token);

      // When any of them complete, cancel the other tasks.
      await NwTask.WhenAny(task1, task2);
      tokenSource.Cancel();
    }
  }
}

Methods

Delay(TimeSpan, CancellationToken?)

Waits until the specified amount of time has passed.

DelayFrame(int, CancellationToken?)

Waits until the specified amount of frames have passed.

NextFrame()

Waits until the next server frame/loop.

Run(Func<Task>)

Queues the specified work to run on the next server cycle.

Run<T>(Func<Task<T>>)

Queues the specified work to run on the next server cycle.

SwitchToMainThread()

Safely returns to a NWScript context from another thread.
This must ALWAYS be called after an external callback, or thread switch before using any NWN APIs.

WaitUntil(Func<bool>, CancellationToken?)

Waits until the specified expression returns true.

WaitUntilValueChanged<T>(Func<T>, CancellationToken?)

Waits until the specified value source changes.

WhenAll(IEnumerable<Task>)

Waits until all the specified tasks have completed.

WhenAll(params Task[])

Waits until all the specified tasks have completed.

WhenAll<TResult>(IEnumerable<Task<TResult>>)

Waits until all the specified tasks have completed.

WhenAll<TResult>(params Task<TResult>[])

Waits until all the specified tasks have completed.

WhenAny(IEnumerable<Task>)

Waits until any of the specified tasks have completed.
NOTE: This will not cancel other tasks that have not finished running. Specify a common CancellationToken in each of the source tasks.

WhenAny(params Task[])

Waits until any of the specified tasks have completed.
NOTE: This will not cancel other tasks that have not finished running. Specify a common CancellationToken in each of the source tasks.

WhenAny<TResult>(IEnumerable<Task<TResult>>)

Waits until any of the specified tasks have completed.
NOTE: This will not cancel other tasks that have not finished running. Specify a common CancellationToken in each of the source tasks.

WhenAny<TResult>(params Task<TResult>[])

Waits until any of the specified tasks have completed.
NOTE: This will not cancel other tasks that have not finished running. Specify a common CancellationToken in each of the source tasks.