How it works
An operation can belong to more than one lifetime. A screen may close, or the whole application may shut down. CreateLinkedTokenSource produces a token that observes cancellation requested through either parent source, allowing the operation to receive one token rather than manually polling several unrelated owners.
Canceling screen requests cancellation of the linked source. It does not cancel shutdown, so the second printed value remains false. Cancellation propagation follows the linkage into the combined source; it does not mean all parent lifetimes become canceled together. This direction matters when several operations share one parent source.
Task.Delay receives the linked token and honors its already-canceled state by completing through cancellation. Catching OperationCanceledException handles that cooperative outcome. The example uses no timing race: the request exists before the delay begins, so the lesson concerns ownership and propagation rather than timer precision.
Dispose the linked source when its lifetime ends so its registrations with parent tokens can be released. Disposing a source is not the same operation as requesting cancellation. Keep the sequence of request, cooperative completion, and disposal clear when a real resource-consuming operation is involved.
Practice by canceling shutdown instead of screen, then by leaving both sources uncanceled. Inspect each parent's state and the linked state before awaiting work. Add a second linked operation that shares shutdown but has its own screen source, and predict which operation is affected when one screen closes.
Finally, decide how a user-facing message distinguishes cancellation reasons. Inspecting the parent tokens can help, but several requests can occur close together, so do not promise a unique historical cause unless you record it explicitly. The token communicates a stop request; your application's lifetime model explains which owners are permitted to make that request.
A working example
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using var screen = new CancellationTokenSource();
using var shutdown = new CancellationTokenSource();
using var linked = CancellationTokenSource.CreateLinkedTokenSource(screen.Token, shutdown.Token);
screen.Cancel();
Console.WriteLine(linked.IsCancellationRequested);
Console.WriteLine(shutdown.IsCancellationRequested);
try { await Task.Delay(1, linked.Token); }
catch (OperationCanceledException) { Console.WriteLine("canceled"); }
Expected output
True False canceled
Linking propagates cancellation into the linked token, not backward into every parent source.