如何优雅地终止 BLOCKED 线程?

2023-12-23

有很多地方可以优雅地终止 C# 线程。然而,它们依赖于循环或循环内执行的 if 条件,这假设该语句将被频繁执行;因此,当stopbool 标志被设置,线程快速退出。

如果我有一个线程的情况不正确怎么办?就我而言,这是一个设置为从服务器接收数据的线程,该线程经常阻塞从输入流读取数据的调用,而尚未提供任何数据,因此它会等待。

这是问题循环中的线程:

    while (true)
        {
            if (EndThread || Commands.EndRcvThread)
            {
                Console.WriteLine("Ending thread.");
                return;
            }

            data = "";
            received = new byte[4096];

            int bytesRead = 0;
            try
            {
                bytesRead = stream.Read(received, 0, 4096);
            }
            catch (Exception e)
            {
                Output.Message(ConsoleColor.DarkRed, "Could not get a response from the server.");
                if (e.GetType() == Type.GetType("System.IO.IOException"))
                {
                    Output.Message(ConsoleColor.DarkRed, "It is likely that the server has shut down.");
                }
            }

            if (bytesRead == 0)
            {
                break;
            }

            int endIndex = received.Length - 1;
            while (endIndex >= 0 && received[endIndex] == 0)
            {
                endIndex--;
            }

            byte[] finalMessage = new byte[endIndex + 1];
            Array.Copy(received, 0, finalMessage, 0, endIndex + 1);

            data = Encoding.ASCII.GetString(finalMessage);

            try
            {
                ProcessMessage(data);
            }
            catch (Exception e)
            {
                Output.Message(ConsoleColor.DarkRed, "Could not process the server's response (" + data + "): " + e.Message);
            }
        }

The if块顶部的语句执行通常的正常停止线程设置的操作:检查标志,如果设置了则终止线程。然而,通常会发现该线程在下面几行等待,即stream.Read.

鉴于此,是否有任何方法可以优雅地终止该线程(即没有Aborting),并清理其资源(有一个客户端需要关闭)?


假设您可以使用异步/任务,则干净停止异步和 IO 操作的方法是使用CancelationToken连接到一个CancelationTokenSource。下面的代码片段展示了其应用于简化版本代码时的用法的简化示例。

class MyNetworkThingy 
{
    public async Task ReceiveAndProcessStuffUntilCancelled(Stream stream, CancellationToken token)
    {
        var received = new byte[4096];
        while (!token.IsCancellationRequested)
        {
            try
            {
                var bytesRead = await stream.ReadAsync(received, 0, 4096, token);
                if (bytesRead == 0 || !DoMessageProcessing(received, bytesRead))
                    break; // done.
            }
            catch (OperationCanceledException)
            {
                break; // operation was canceled.
            }
            catch (Exception e)
            {
                // report error & decide if you want to give up or retry.
            }
        }
    }

    private bool DoMessageProcessing(byte[] buffer, int nBytes)
    {
        try
        {
            // Your processing code.
            // You could also make this async in case it does any I/O.
            return true;
        }
        catch (Exception e)
        {
            // report error, and decide what to do.
            // return false if the task should not
            // continue.
            return false;
        }
    }
}

class Program
{
    public static void Main(params string[] args)
    {
        using (var cancelSource = new CancellationTokenSource())
        using (var myStream = /* create the stream */)
        {
            var receive = new MyNetworkThingy().ReceiveAndProcessStuffUntilCancelled(myStream, cancelSource.Token);
            Console.WriteLine("Press <ENTER> to stop");
            Console.ReadLine();
            cancelSource.Cancel();
            receive.Wait();
        }
    }
}

.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何优雅地终止 BLOCKED 线程? 的相关文章

  • 如何保证对象只有一个线程

    我有以下代码 class Service public void start creates thread which creates window and goes to message loop void stop sends WM C
  • 何时使用 =default 使析构函数默认?

    尽管对构造函数使用 default 对我来说很清楚 即强制编译器在其他构造函数存在时创建默认构造函数 但我仍然无法理解这两种类型的析构函数之间的区别 那些使用 default 的 那些没有显式定义并由编译器自动生成的 我唯一想到的是 gro
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 如何在 C# / .NET 中创建内存泄漏[重复]

    这个问题在这里已经有答案了 可能的重复 托管代码中是否可能存在内存泄漏 特别是 C 3 0 https stackoverflow com questions 6436620 is it possible to have a memory
  • 根据 N 个值中最小的一个返回不同的结果

    不确定如何使标题更具描述性 所以我只是从一个例子开始 我使用下面的代码位 它从枚举中选择一个方向 具体取决于四个轴中哪一个与给定方向相比形成最小角度 static Direction VectorToDirection Vector2 di
  • 信号处理程序有单独的堆栈吗?

    信号处理程序是否有单独的堆栈 就像每个线程都有单独的堆栈一样 这是在 Linux C 环境中 来自 Linux 手册页signal 7 http kernel org doc man pages online pages man7 sign
  • 指向特征矩阵的指针数组

    我在代码中使用 Eigen 的 MatrixXd 矩阵 在某个时刻我需要一个 3D 矩阵 由于 Eigen 没有三维矩阵类型 因为它仅针对线性代数进行了优化 因此我创建了一个 MatrixXd 类型的指针数组 Eigen MatrixXd
  • 单例模式和 std::unique_ptr

    std unique ptr唯一地控制它指向的对象 因此不使用引用计数 单例确保利用引用计数只能创建一个对象 那么会std unique ptr与单例执行相同 单例确保只有一个实例属于一种类型 A unique ptr确保只有一个智能指针到
  • Visual Studio Code:如何配置 includePath 以获得更好的 IntelliSense 结果

    我是使用 Visual Studio Code 的完全初学者 我不知道我在做什么 我已经四处搜索 也许还不够 但我找不到像我这样的人如何配置的简单解释c cpp properties json每当我单击带有绿色波浪线下划线的行旁边的黄色灯泡
  • C# 构建一个 webservice 方法,它接受 POST 方法,如 HttpWebRequest 方法

    我需要一个接受 POST 方法的 Web 服务 访问我的服务器正在使用 POST 方法 它向我发送了一个 xml 我应该用一些 xml 进行响应 另一方面 当我访问他时 我已经使用 HttpWebRequest 类进行了管理 并且工作正常
  • 给出 5 个参数,但在终端中只得到 3 个参数

    我想将一个文件传递给一个c 程序 如果我在 IDE 中执行此操作 test string string lt test txt return argc 5 但在终端上我刚刚得到argc 3 看来 这是因为 什么是 lt 意思是 我正在使用
  • 如何在标准 WPF ListView 中启用 UI 虚拟化

    我正在使用 NET 4 5 VS2012 并且我有一个 ListView 看起来像这样
  • 我可以让 ungetc 取消阻止阻塞的 fgetc 调用吗?

    我想在收到 SIGUSR1 后使用 ungetc 将 A 字符重新填充到标准输入中 想象一下我有充分的理由这样做 调用 foo 时 stdin 中的阻塞读取不会被收到信号时的 ungetc 调用中断 虽然我没想到它会按原样工作 但我想知道是
  • 了解使用 Windows 本机 WPF 客户端进行 ADFS 登录

    我已经阅读了大量有关 ADFS 与 NodeJS Angular 或其他前端 Web 框架集成以及一般流程如何工作的文献 并通过 Auth0 Angular 起始代码构建了概念证明 但我不明白如何这可以与本机 WPF Windows 应用程
  • 终结器线程的范围是什么 - 每个应用程序域或每个进程?

    根据我的所有阅读 应该有一个 GC 线程来调用所有终结器 现在的问题是这个 一个 线程的范围是什么 每个进程或每个应用程序域 因为域的整体目的是在一个进程空间中分离并创建 独立 的不同应用程序 I read here http dn cod
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • 每个数据库多个/单个 *.edmx 文件

    我有一个通过 ADO net 数据服务与数据库交互的项目 数据库很大 近 150 个具有依赖关系的表 该项目几年前开始 当时使用的是数据集 现在我们正在转向实体模型关系 由于我们添加了更多需要使用的表 该模型正在不断增长 这是管理这一切的正
  • 更改 Windows Phone 系统托盘颜色

    有没有办法将 Windows Phone 上的系统托盘颜色从黑色更改为白色 我的应用程序有白色背景 所以我希望系统托盘也是白色的 您可以在页面 XAML 中执行此操作
  • 使我的 COM 程序集调用异步

    我刚刚 赢得 了在当前工作中维护用 C 编码的遗留库的特权 这个dll 公开使用 Uniface 构建的大型遗留系统的方法 除了调用 COM 对象之外别无选择 充当此遗留系统与另一个系统的 API 之间的链接 在某些情况下 使用 WinFo
  • xsi:type 属性搞乱了 C# XML 反序列化

    我使用 XSD exe 根据 XML 架构 xsd 文件 自动生成 C 对象 我正在反序列化 OpenCover 输出 但其中一个部分类未正确生成 这是导致异常的行

随机推荐

  • Android:如何根据设备时区获取默认日期格式

    有没有简单的方法可以根据用户的时区获取默认日期格式 The SimpleDateFormat 给出根据用户区域设置的日期格式 我正在寻找一种场景 需要将提供的日期转换为基于时区的日期格式 例如 用户将其区域设置设置为 中文 并且采用德国时区
  • Java 最小化依赖关系

    我遇到过这样的情况 一小段Java代码有大量依赖的jar 然而 这些 jar 内部的依赖关系非常浅 在大多数情况下 它仅依赖于单个接口的 jar 我不想将所有 jar 与应用程序一起分发 而是只想将特定的类文件分发到它实际使用的 jar 中
  • 记录 JUnit 测试运行所需的时间

    我想记录我的 JUnit 测试以编程方式运行需要多长时间 我在各种测试类中有大量测试 我想了解每个单独的测试方法运行需要多长时间 我可以更改继承结构或以不同方式注释方法 但我希望避免在测试方法本身以及用于设置测试业务逻辑的之前 之后方法中添
  • Git 说是最新的,尽管更改是远程进行的

    使用 git bash 我在我的主分支上工作 推送它并决定我想要实现一个新功能 我为此创建了一个新分支 后来我添加了另一个功能 创建了另一个分支 我测试了所有内容并且它正常工作 所以我决定将所有内容合并到我的主分支 我将两个新分支推送到远程
  • 如何将.plist文件中的数据结构读取到NSArray中

    我正在使用以下内容手动创建数据结构 NSDictionary league1 NSDictionary alloc initWithObjectsAndKeys Barclays Premier League name Premier Le
  • 如何从路径中删除 Microsoft.PowerShell.Core\FileSystem::\\

    我正在使用 powershell 与文件夹及其所有子文件夹进行比较 并且它在我的本地计算机上工作正常 但是当我在服务器上尝试它时 它给了我错误并附加 Microsoft PowerShell Core FileSystem 到所有文件 如果
  • 如何使用 PHP 将元素添加到 JSON 对象? [复制]

    这个问题在这里已经有答案了 我有这个 JSON 数组 我想使用 PHP 向其中添加另一个值 使用 PHP 将 ID 和名称添加到该数组的最简单方法是什么 id 1 name Charlie id 2 name Brown id 3 name
  • 获取node.js应用程序的最大堆大小

    现在我在paas平台上使用node js 并且容器有内存限制 现在我想获取node js应用程序的堆大小的最大值 我知道使用参数 max old space size 我可以设置最大堆大小 但我想知道如何获取 max old space s
  • Selenium Webdriver sendkeys 在 IE9.0 中不触发 onchange 事件

    我正在使用 Java 为 ExtJs 中构建的应用程序编写 Selenium 测试脚本 我在附加到 onchange 事件的页面之一中有一个输入字段 每当用户修改字段中的文本时 就会触发 onchange 事件 我正在使用 WebDrive
  • 在 PyDev 控制台中停止正在运行的命令

    我使用 PyDev 控制台运行长脚本 并且经常希望在命令中间停止 在常规 python shell 中 我按 ctrl c 它会通过键盘中断停止命令 但在 PyDev 控制台中 它会进行文本复制 如何停止此控制台中的命令而不终止它 如果您使
  • 何时应使用 Readonly 和 Get only 属性

    在 NET 应用程序中 何时应使用 ReadOnly 属性 何时应仅使用 Get 这两者有什么区别呢 private readonly double Fuel 0 public double FuelConsumption get retu
  • @TargetApi 注解仅适用于一个 Api 级别或更高级别吗?

    我在我的应用程序中使用 TargetApi 23 TargetApi 23 Override public void onAttach Context context super onAttach context onAttachToCon
  • BigQuery 中交叉联接后的行聚合

    假设您在 BigQuery 中有下表 A user1 0 0 user2 0 3 user3 4 0 交叉连接后 您有 dist user1 user2 0 0 0 3 comma is just showing user val sepe
  • LOAD DATA LOCAL INFILE 导致 mysql2 gem 出现格式错误的数据包错误

    我正在尝试发出 LOAD DATA LOCAL INFILE 查询 以使用 Rails 3 1 1 下的 mysql2 gem 0 3 11 将一些 CSV 数据加载到表中 class Foo lt ActiveRecord Base de
  • 减小图像大小 C# [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我的场景 我希望减少图像大小 10 KB 到 3 KB 好吧 你想要的可以是这样的 Make sure to include this
  • 操作无法完成。无效指针 - Visual Studio 2015 更新 3

    打开时出现这个错误 cshtml file 操作无法完成 无效指针 安装更新 3 和 Net Core 后一切都会开始 MVC 核心应用程序 cshtml文件正确打开 请清除 Visual Studio 组件缓存 重新启动 Visual S
  • 使用 VTK 的 Python 可执行文件... pyinstaller、py2exe、cx_freeze 等

    我使用 pyqt 在 python 中构建了一个 gui 它导入了 VTK 我没有运气让 py2exe pyinstaller cx freeze 等使用它 我收到一个错误 使用 pyinstaller 说出以下内容 vtk helper
  • 从 GridView 中删除列

    我有一个带有几列的 GridView 我不想将其导出为 PDF 通过 iTextSharp 如何在导出数据之前隐藏不想导出的列 在导出数据之前 请执行以下操作 myGridView columns RemoveAt index Index
  • jQuery 检测移动 Safari/iOS 上的页面底部

    我基本上想要与 facebook twitter 和所有其他 无限 滚动网站相同的功能 我目前使用的代码是 jQuery document ready function jQuery window scroll function if io
  • 如何优雅地终止 BLOCKED 线程?

    有很多地方可以优雅地终止 C 线程 然而 它们依赖于循环或循环内执行的 if 条件 这假设该语句将被频繁执行 因此 当stopbool 标志被设置 线程快速退出 如果我有一个线程的情况不正确怎么办 就我而言 这是一个设置为从服务器接收数据的