Cancel specific child thread or task after unsubscribing socket stream

筅森魡賤 提交于 2019-12-24 10:11:02

问题


I'm trying to run multi-threaded tasks under main task using following code but not working expectedly.

CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;

using (var socketClient = new SocketClient()) {
  Task.Factory.StartNew(() => {
    Console.WriteLine("Starting child task...");
    if (cancellationToken.IsCancellationRequested) {
        Console.WriteLine("Task cancellation requested");
        throw new OperationCanceledException(cancellationToken);
    }

    List<string> pairsList = db.GetPairsList(); //loads from db and it's dynamic
    try {
        // loop through each pair
        Parallel.ForEach(pairsList, pair => {
            Console.WriteLine("Item {0} has {1} characters", pair, pair.Length);
            SubscribeToStream(socketClient);//I'm subscribing to some socket streams 
        });
    } catch (OperationCanceledException ex) {
        Console.WriteLine(ex.Message);
    }
  }, cancellationToken);
}

Subscribe method is as follows:

private void SubscribeToStream(string pair, SocketClient socketClient) {
    var subscribePair = socketClient.SubscribeToPair(pair, data => {             
         //here socket stream returns callback each second for each pair
         Application.Current.Dispatcher.Invoke(() => {
              //if perfect match found then Remove pair from the list
              if(a == b) {
                 db.removePair(pair);
              }
              //after removing refresh new pairs list to see if new pair added or removed from the main list from db..
         }
         //after match, we need to unsubscribe from the current pair
         socketClient.UnsubscribeFromPair(subscribePair.Data);

         //IT CALLS SAME PAIR AGAIN EVEN AFTER UNSUBSCRIBING FROM SOCKET STREAM
    }
}

I want to run a main task which holds child tasks separately. Start button will start main thread and Stop button will stop all threads safely along with main thread.

Each child thread subscribed to some socket streams which runs for each pairs. If matched data found then I'm removing that pair from the pairs list but thread continues due to stream subscription or thread might not been cancelled successfully. However, I'm able to cancel the main thread but I want to cancel specific thread/task not the main task and allow the main task continues along with existing or newly added pairs.

How can we safely achieve this scenario?


回答1:


For every thread/task you want to cancel, you need to forward it the cancellationToken and check for that repeatedly. So you need to make sure your inner Task (in the Parallel.ForEach loop) also repeatedly checks the cancellationToken and aborts if it is triggered.

Hint: It is good practice to always keep a reference to created tasks, to be able to check whether it has really ended. So keep a reference to the return value of Factory.StartNew() and use it later to check that the task has really ended.



来源:https://stackoverflow.com/questions/49217722/cancel-specific-child-thread-or-task-after-unsubscribing-socket-stream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!