Thread/Task cancellation

Ruby The Roobster michaeleverestc79 at gmail.com
Fri Jul 28 18:52:59 UTC 2023


On Friday, 28 July 2023 at 18:17:18 UTC, Gjiergji wrote:
> I am coming from a C# background. I understood that there is no 
> async/await equivalent in D (except fibers which are not 
> suitable for multi threading), but if I am using threads, what 
> is the D idiom to implement cancellation?
>
> Usually a long running thread looks like this (in C#):
>
> ```csharp
> try
> {
>    while (!cancellationToken.IsCancellationRequested)
>    {
>       //do some work
>       await SomethingAsync(cancellationToken);
>       //do some other work
>       await Task.Delay(TimeSpan.FromSeconds(5000), 
> cancellationToken);
>    }
> }
> catch (OperationCancelledException e) when (e.Token == 
> cancellationToken)
> {
>    //someone cancelled any of the await calls above, we can 
> swallow it or log it
> }
>
> ```
>
> The question is how do I pass a `cancellationToken` to the 
> calls from the loop in order to terminate them before 
> completion. For example, I learnt about `Thread.sleep` in 
> phobos, but I cannot pass a cancellation token in order to 
> cancel it before the intended sleep duration.
>
> Thx.


You could use a thread to check if the token has been sent via 
message passing, and when it is sent, throw an exception, like 
this:

```d
import std.concurrency;

Tid tid;

void foo()
{
     try
     {
         tid = spawn(&bar);
         // do stuff
     }
     catch(Exception e)
     {
         // ...
     }
}

void bar()
{
     bool terminate = false;
     terminate = receiveOnly!bool();
     if(terminate)
     {
         throw new Exception("Thread terminated");
     }
}

void main()
{
     spawn(&foo);
     // ...
     if(needsToTerminateFooForSomeReason)
         tid.send(true);
     // ...
}
```

This does however, terminate with signal 11 upon sending the 
terminate signal, and I'm not sure why.



More information about the Digitalmars-d-learn mailing list