c# - 取消订阅套接字流后取消特定的子线程或任务

标签 c# multithreading websocket task

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

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

我想运行一个单独包含子任务的主任务。 Start 按钮将启动主线程,Stop 按钮将与主线程一起安全地停止所有线程。

每个子线程都订阅了一些为每对运行的套接字流。如果找到匹配的数据,那么我将从配对列表中删除该对,但由于流订阅或线程可能未成功取消,线程继续。但是,我可以取消主线程,但我想取消特定线程/任务而不是主任务,并允许主任务与现有或新添加的对一起继续。

我们如何才能安全地实现这种情况?

最佳答案

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

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

关于c# - 取消订阅套接字流后取消特定的子线程或任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49217722/

相关文章:

c# - 将 c++ std::string 转换为 c# 字节数组

c# - 没有 Visual Studio 的引用 Web 服务

java - 简单计算在多线程中比在单线程中花费更长的时间

c# - 从 WPF 执行存储过程

c - 为什么这段代码在没有 volatile 声明的情况下会失败?

java - 基于触发器java运行任务

linux - 如何在 docker 容器中安装插件?

java - Websocket 客户端找不到实现类

cordova - 如何解决或绕过错误 websocket : origin not allowed

c# - 在 EF Core 中添加一对一关系时迁移数据?