0

I want if the user changed the listbox item and the previous task was not complete yet, that task stops and a new task starts. How can i do this?
I used this code but not work.

CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token;
private void Listbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (task != null && (task.IsCompleted == false || task.Status == TaskStatus.Running))
    {
        if (source != null)
            source.Cancel();
    }

    task = LoadArts();
}

private async Task LoadArts()
{
    token = source.Token;
    await Task.Run(() =>
    {
    }

    , token);
}
FCin
  • 3,804
  • 4
  • 20
  • 49
  • 1
    Cancellation doesn't just happen. You need to have code acts in the task you're running. You haven't shown us your code but see https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation and https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-cancel-a-task-and-its-children From the latter "Notice and respond to the cancellation request in your user delegate." It can be more convenient to simply ignore what comes back from a task (which is on anther thread anyhow) rather than try and cancel it. – Andy Feb 01 '19 at 12:32
  • 1
    Rather than canceling current task (might be hard to achieve) consider to use queue. In simplest form you can use `ContinueWith` (see [TaskQueue](https://stackoverflow.com/a/32993768/1997232)). You can split `LoadArts` in 2 distinct parts: to load data and to display them, before each you can check if queue is empty and exit task if it's not. `ContinueWith` will take care to run next task (and they are all exit immediately if queue is still not empty), until the very last item, which then able to pass display check and you will finally see something on display. – Sinatr Feb 01 '19 at 12:45

1 Answers1

0
  1. You should pass the CancellationToken to the code that runs in the task and call the ThrowIfCancellationRequested method on the token from time to time from it.
  2. You should pass the cancellation token to the Task.Run method after your delegate. Since cancellation is done by throwing an OperationCanceledException or a TaskCanceledException, the task's status will become faulted since an exception was thrown in it. When you pass the token, the task compares it to the token in the cancellation exception, and if they match the task becomes canceled, not faulted.
haimb
  • 381
  • 3
  • 4