取消订阅套接字流后取消特定的子线程或任务 [英] Cancel specific child thread or task after unsubscribing socket stream

查看:34
本文介绍了取消订阅套接字流后取消特定的子线程或任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用以下代码在主任务下运行多线程任务,但没有按预期工作.

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);
}

订阅方法如下:

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?

推荐答案

对于每个要取消的线程/任务,您都需要将取消令牌转发给它并反复检查.所以你需要确保你的内部任务(在 Parallel.ForEach 循环中)也重复检查取消令牌并在它被触发时中止.

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.

提示:始终保留对已创建任务的引用是一种很好的做法,以便能够检查它是否真的结束了.因此保留对 Factory.StartNew() 返回值的引用,稍后使用它来检查任务是否真的结束.

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.

这篇关于取消订阅套接字流后取消特定的子线程或任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆