Search code examples
c#task-parallel-librarycancellationtokensourcecancellation-token

Cancel token only for one task out of list of tasks


In one of my project I have requirement to add Tasks for each new entry that we add for customer and these tasks are created using LongRunning options so that as when we receive any request from this customer all these requests needs to be processed from backend service only.

Below is sample code piece where I add customer to task and when customer do not want to associate with us then we remove from task

public Dictionary _cancellationTokenSourcesForChannels = new Dictionary();

public void AddCustomerToTask(int custId, CancellationToken cancelToken)
    {            
        var cust = custSvc.SessionFactory.OpenSession().Get<Customer>(custId);
        var custModel = new CustomerModel().FromCustomer(cust);

        var tokenSource = new CancellationTokenSource();
        var taskPoller = new Task(() => WindowsService.Start(custModel), tokenSource.Token,
            TaskCreationOptions.LongRunning);
        taskPoller.Start();

        //Maintaining list of cancellationTokenSource in Dictionary
        if (_cancellationTokenSourcesForChannels == null)
            _cancellationTokenSourcesForChannels = new Dictionary<int, CancellationTokenSource>();
        if (_cancellationTokenSourcesForChannels.ContainsKey(custId))
            _cancellationTokenSourcesForChannels.Remove(custId);

        _cancellationTokenSourcesForChannels.Add(custId, tokenSource);
    }

    public void RemoveCustomerFromTask(int custId)
    {
        CancellationTokenSource currentToken;
        if (_cancellationTokenSourcesForChannels.ContainsKey(custId))
        {
            _cancellationTokenSourcesForChannels.TryGetValue(custId, out currentToken);
            currentToken?.Cancel();
        }
        if (_cancellationTokenSourcesForChannels.ContainsKey(custId))
            _cancellationTokenSourcesForChannels.Remove(custId);
    }

So, my question is that when I make request to remove customer who do not want to associate, then I call to RemoveCustomerFromTask(custId), then basically code is trying to cancel the task for this customer. But interestingly it is cancelling all the tasks which were created for other customers also.

Could you anyone please help me here how to rectify my issue?

I am maintaining the list of canceltoken into the dictionary to remove when I call RemoveCustomerFromTask method.


Solution

  • I ended up having creating all tasks to the dictionary along with their cancel tokens. Whenever it is required for me to cancel any taks, I am getting that from dictionary and stopping and cancelling by using its own cancel token.

    Dictionary uses my own class which holds Task and Cancel Token information.