public void CancelableMethodWithOverload(CancellationToken cancellationToken)
{
    // tu wstawiamy kod
}

public void CancelableMethodWithOverload()
{
    CancelableMethodWithOverload(CancellationToken.None);
}

public void CancelableMethodWithDefault(
    CancellationToken cancellationToken = default(CancellationToken))
{
    // tu wstawiamy kod
}

---

void IssueCancelRequest()
{
    var cts = new CancellationTokenSource();
    var task = CancelableMethodAsync(cts.Token);

    // Na tym etapie operacja została uruchomiona.

    // Wysłanie żądania anulowania.
    cts.Cancel();
}

---

async Task IssueCancelRequestAsync()
{
    var cts = new CancellationTokenSource();
    var task = CancelableMethodAsync(cts.Token);

    // Na tym etapie operacja została szczęśliwie uruchomiona.

    // Wysłanie żądania anulowania.
    cts.Cancel();

    // (Asynchroniczne) oczekiwanie na zakończenie operacji.
    try
    {
        await task;
        // Jeśli dotarliśmy tutaj, operacja została zakończona z powodzeniem, zanim anulowanie odniosło skutek.
    }
    catch (OperationCanceledException)
    {
        // Jeśli dotarliśmy tutaj, operacja została anulowana, zanim została zakończona.
    }
    catch (Exception)
    {
        // Jeśli dotarliśmy tutaj, operacja została zakończona z błędem, zanim anulowanie odniosło skutek.
        throw;
    }
}

---

private CancellationTokenSource _cts;

private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    StartButton.IsEnabled = false;
    CancelButton.IsEnabled = true;
    try
    {
        _cts = new CancellationTokenSource();
        var token = _cts.Token;
        await Task.Delay(TimeSpan.FromSeconds(5), token);
        MessageBox.Show("Opóźnienie zakończone z powodzeniem.");
    }
    catch (OperationCanceledException)
    {
        MessageBox.Show("Opóźnienie zostało anulowane.");
    }
    catch (Exception)
    {
        MessageBox.Show("Opóźnienie zakończone z błędem.");
        throw;
    }
    finally
    {
        StartButton.IsEnabled = true;
        CancelButton.IsEnabled = false;
    }
}

private void CancelButton_Click(object sender, RoutedEventArgs e)
{
    _cts.Cancel();
}

---

public int CancelableMethod(CancellationToken cancellationToken)
{
    for (int i = 0; i != 100; ++i)
    {
        Thread.Sleep(1000); // Tu wykonywane są pewne obliczenia.
        cancellationToken.ThrowIfCancellationRequested();
    }
    return 42;
}

---

public int CancelableMethod(CancellationToken cancellationToken)
{
    for (int i = 0; i != 100000; ++i)
    {
    Thread.Sleep(1); // Tu wykonywane są pewne obliczenia.
    if (i % 1000 == 0)
        cancellationToken.ThrowIfCancellationRequested();
    }
    return 42;
}

---

async Task IssueTimeoutAsync()
{
    var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
    var token = cts.Token;
    await Task.Delay(TimeSpan.FromSeconds(10), token);
}

---

async Task IssueTimeoutAsync()
{
    var cts = new CancellationTokenSource();
    var token = cts.Token;
    cts.CancelAfter(TimeSpan.FromSeconds(5));
    await Task.Delay(TimeSpan.FromSeconds(10), token);
}

---

public async Task<int> CancelableMethodAsync(CancellationToken cancellationToken)
{
    await Task.Delay(TimeSpan.FromSeconds(2), cancellationToken);
    return 42;
}

---

static void RotateMatrices(IEnumerable<Matrix> matrices, float degrees,
    CancellationToken token)
{
    Parallel.ForEach(matrices,
        new ParallelOptions { CancellationToken = token },
        matrix => matrix.Rotate(degrees));
}

---

static void RotateMatrices2(IEnumerable<Matrix> matrices, float degrees,
    CancellationToken token)
{
    // Uwaga: niezalecane; zobacz poniżej.
    Parallel.ForEach(matrices, matrix =>
    {
        matrix.Rotate(degrees);
        token.ThrowIfCancellationRequested();
    });
}

---

static IEnumerable<int> MultiplyBy2(IEnumerable<int> values,
    CancellationToken cancellationToken)
{
    return values.AsParallel()
        .WithCancellation(cancellationToken)
        .Select(item => item * 2);
}

---

private IDisposable _mouseMovesSubscription;

private void StartButton_Click(object sender, RoutedEventArgs e)
{
    var mouseMoves = Observable
        .FromEventPattern<MouseEventHandler, MouseEventArgs>(
            handler => (s, a) => handler(s, a),
            handler => MouseMove += handler,
            handler => MouseMove -= handler)
        .Select(x => x.EventArgs.GetPosition(this));
    _mouseMovesSubscription = mouseMoves.Subscribe(val =>
    {
        MousePositionLabel.Content = "(" + val.X + ", " + val.Y + ")" ;
    });
}

private void CancelButton_Click(object sender, RoutedEventArgs e)
{
    if (_mouseMovesSubscription != null)
        _mouseMovesSubscription.Dispose();
}

---

CancellationToken cancellationToken = ...
IObservable<int> observable = ...
int lastElement = await observable.TakeLast(1).ToTask(cancellationToken);
// lub: int lastElement = await observable.ToTask(cancellationToken);

---

CancellationToken cancellationToken = ...
IObservable<int> observable = ...
int firstElement = await observable.Take(1).ToTask(cancellationToken);

---

CancellationToken cancellationToken = ...
IObservable<int> observable = ...
IList<int> allElements = await observable.ToList().ToTask(cancellationToken);

---

using (var cancellation = new CancellationDisposable())
{
    CancellationToken token = cancellation.Token;
    // Przekazanie tokena do metod, które na niego reagują.
}

---

IPropagatorBlock<int, int> CreateMyCustomBlock(
    CancellationToken cancellationToken)
{
    var blockOptions = new ExecutionDataflowBlockOptions
    {
        CancellationToken = cancellationToken
    };
    var multiplyBlock = new TransformBlock<int, int>(item => item * 2,
        blockOptions);
    var addBlock = new TransformBlock<int, int>(item => item + 2,
        blockOptions);
    var divideBlock = new TransformBlock<int, int>(item => item / 2,
        blockOptions);

    var flowCompletion = new DataflowLinkOptions
    {
        PropagateCompletion = true
    };
    multiplyBlock.LinkTo(addBlock, flowCompletion);
    addBlock.LinkTo(divideBlock, flowCompletion);

    return DataflowBlock.Encapsulate(multiplyBlock, divideBlock);
}

---

async Task<HttpResponseMessage> GetWithTimeoutAsync(string url,
    CancellationToken cancellationToken)
{
    var client = new HttpClient();

    using (var cts = CancellationTokenSource
        .CreateLinkedTokenSource(cancellationToken))
    {
        cts.CancelAfter(TimeSpan.FromSeconds(2));
        var combinedToken = cts.Token;
        return await client.GetAsync(url, combinedToken);
    }
}

---

async Task<PingReply> PingAsync(string hostNameOrAddress,
    CancellationToken cancellationToken)
{
    var ping = new Ping();
    using (cancellationToken.Register(() => ping.SendAsyncCancel()))
    {
        return await ping.SendPingAsync(hostNameOrAddress);
    }
}

---

