digitalmars.D.learn - Thread/Task cancellation
- Gjiergji (30/30) Jul 28 2023 I am coming from a C# background. I understood that there is no
- Ruby The Roobster (39/69) Jul 28 2023 You could use a thread to check if the token has been sent via
- Ruby The Roobster (38/80) Jul 28 2023 Ignore my above code, Here is something that should work:
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?
```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.
Jul 28 2023
On Friday, 28 July 2023 at 18:17:18 UTC, Gjiergji wrote:
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?
```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.
Jul 28 2023
On Friday, 28 July 2023 at 18:52:59 UTC, Ruby The Roobster wrote:On Friday, 28 July 2023 at 18:17:18 UTC, Gjiergji wrote: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? ```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.[SNIP]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:This does however, terminate with signal 11 upon sending the terminate signal, and I'm not sure why.Ignore my above code, Here is something that should work: ```d import std.concurrency; void foo() { try { auto tid = spawnLinked(&bar); ownerTid.send(tid); // do stuff // ... auto c = receiveTimeout(0.msecs, (ubyte a) {}); // Since bar is linked, this will throw an exception when bar terminates } catch(Exception e) { // Do whatever with the exception message, but it terminates the function execution. } } void bar() { bool terminate = false; terminate = receiveOnly!bool(); } void main() { spawn(&foo); Tid tid = receiveOnly!Tid(); // ... if(needsToTerminateFooForSomeReason) tid.send(true); // ... } ``` This is the only way I could think of doing this, since exceptions don't travel up the threads.
Jul 28 2023








Ruby The Roobster <michaeleverestc79 gmail.com>