C#.NET 线程问题

2023-12-04

我面临 C#.NET 应用程序中线程之间通信的问题。 希望有人能指导我找到可能的解决方案的正确方向。

我有一个 C#.NET 中的应用程序。它是一个 Windows 窗体应用程序。 我的应用程序有两个线程 - 一个线程是主线程(UI 线程),另一个线程是子线程。我们将子线程称为“workerThread” 应用程序中仅使用一种表单。让我们将此表单称为“MainForm”

子线程在 MainForm 加载时启动(使用表单的“Load”事件处理程序启动线程)

在 MainForm 类中,我有一个名为“stopWork”的变量,它是一个公共布尔变量,它用作指示子线程是否应该继续工作或应该停止的标志

我有另一个类(除了 MainForm 类),其中包含我在子线程中执行的方法。我们将第二个类称为“WorkerClass”。 我将对当前表单(MainForm)的引用传递到“WorkerClass”的构造函数中

我在主窗体中有一个按钮“stop”,如果单击它,则将“stopWork”设置为“true”,然后调用“workerThread.Join()”以等待子线程完成执行。

在子线程中,方法“doWork”不断检查“parentForm.stopWork”内部的状态for环形。如果“stopWork”设置为“true”,则循环中断,随后该方法结束。

现在的问题是,一旦我单击“停止”按钮,应用程序就会挂起。

我粘贴了下面的部分代码,以便更容易理解:

public partial class MainForm : Form
{
    Thread workerThread = null;
    ThreadStart workerThreadStart = null;
    WorkerClass workerClass = null;

    public bool stopWork = true;

    /*.......... some code ............*/

    private void MainForm_Load(object sender, EventArgs e)
    {
        workerThreadStart = new ThreadStart(startWork);
        workerThread = new Thread(workerThreadStart);
        stopWork = false;
        workerThread.Start();
    }

    private void startWork()
    {
        workerClass = new WorkerClass(this);
    }

    private void buttonStop_Click(object sender, EventArgs e)   //"stop" button
    {
        if (workerThread != null)
        {
            if (workerThread.IsAlive == true)
            {
                stopWork = true;
                workerThread.Join();
            }
        }
    }

    /*.......... some more code ............*/

}

public class WorkerClass
{
    MainForm parentForm=null;

    /*......... some variables and code ........*/

    public WorkerClass(MainForm parentForm)
    {
        this.parentForm=parentForm;
    }

    /* .............. some more code ...........*/

    public void doWork()
    {
       /*.......... some variables and code ...........*/

       for(int i=0;i<100000;i++)
       {
           // ** Here is the check to see if parentForm has set stopWork to true **
           if(parentForm.stopWork==true)
              break;

           /*......... do some work in the loop ..........*/


       }

    }

    /********* and more code .........*/
}

我想我可能知道问题出在哪里了。 问题出在子线程中的“doWork”方法试图访问父窗体中的“stopWork”变量,而父窗体已经通过调用“workerThread.Join()”方法被阻止。所以,我认为这是一个“僵局”问题。

我对问题的识别正确吗?或者我错了,问题出在其他地方?

如果这确实是一个僵局,有哪些可能的解决方案可以解决这个问题?

我做了一些谷歌搜索,发现了很多关于线程同步以及如何避免死锁的资源。但我不明白如何将它们专门应用于我的问题。

我非常感谢有关解决此问题的任何帮助或指导。


是的,你写的代码是highly容易陷入僵局。 BackgroundWorker 类特别容易导致这种死锁。

问题出在我们在您的代码片段中看不到的代码中,即 WorkerClass。您肯定正在做一些以某种方式影响 UI 的事情,这始终是首先考虑创建线程的主要原因。您可能使用 Control.Invoke() 在 UI 线程上运行一些代码并更新控件。也许还可以发出工作线程已完成的信号,例如将按钮的 Enable 属性设置回 true。

这就是死锁城市,这样的代码无法运行,直到 UI 线程空闲,返回到消息循环。在你的情况下它永远不会空闲,它被困在 Thread.Join() 中。工作线程无法完成,因为 UI 线程不会空闲,UI 线程无法空闲,因为工作线程尚未完成。僵局。

BackgroundWorker也有这个问题,除非UI线程空闲,否则RunWorkerCompleted事件无法运行。你需要做的是not阻塞 UI 线程。说起来容易做起来难,BGW 可以帮助您正确完成此任务,因为它会在事件完成时运行该事件。您可以让此事件执行您现在在 Thread.Join() 调用之后的代码中执行的任何操作。您的类中需要一个布尔标志来指示您处于“等待完成”状态。这个答案有相关代码。

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

C#.NET 线程问题 的相关文章

  • 是否有可能劫持标准输出

    我正在尝试使用 C 重定向 Windows XP 上已运行进程的标准输出 我知道如果我自己生成进程 我可以做到这一点 但对于这个应用程序 我更喜欢一个 监听器 我可以附加到另一个进程 这在纯 Net 中可能吗 如果不可能 在 Win32 中
  • .crt 部分?这个警告是什么意思?

    我最近收到此警告 VC 2010 warning LNK4210 CRT section exists there may be unhandled static initializers or terminators 我假设这是关键部分
  • NDK 应用 onDestroy 清理 - 如何 DetachCurrentThread

    因此 如果我们连接 我们必须在完成后分离线程 对吗 JNIEnv get jni env JNIEnv res JAVA VM gt GetEnv void res JNI VERSION 1 6 Using cached JavaVM J
  • 将公历日期转换为儒略日期,然后再转换回来(随着时间)

    我正在编写一个程序 必须将当前的公历日期和时间转换为儒略日期 然后再转换回公历门 最终我需要添加能够添加年 月 日 小时 分钟和秒的功能 但我需要先解决这部分问题 现在我已经从公历日期转换为儒略日期 所以从逻辑上讲 我觉得我应该能够以某种方
  • ContentDialog 未与 UWP 中心对齐

    据我所知 ContentDialog的默认行为应该是使其在 PC 上居中并在移动设备上与顶部对齐 但就我而言 即使在 PC 上我也将其与顶部对齐 但我不明白发生了什么 我正在使用代码隐藏来创建它 这是我正在使用的代码片段 Creates t
  • 将 dataGridView 中选定的行作为对象检索

    我有一堂这样的课 public partial class AdressBokPerson public long Session get set public string F rnamn get set public string Ef
  • opencv中如何去除二值图像噪声?

    将图像转换为二值图像 黑白 后如果有任何噪音怎么办 我消除了那些不需要的噪音 您可以看到下图的黑色区域内有一些白噪声 我该如何去除噪声 使用opencv http img857 imageshack us img857 999 blackn
  • 如何将 Q 格式整数转换为浮点数(反之亦然)?

    我四处搜寻 找不到一个很好的问题来回答这个问题 给定一个整数 使用Q Format https en wikipedia org wiki Q number format 如何将该数字转换为普通浮点类型 反之亦然 如何将浮点类型转换为Q F
  • 控制台应用程序中使用 Unicode 字符的 _tprintf

    我正在从 Unicode 构建的控制台应用程序 使用 C 和 Visual Studio 2008 执行这个简单的输出 此代码旨在在 Windows 上运行 tprintf L Some sample string n 一切正常 但是如果我
  • 如何将STL容器数据转储到gdb中?

    我无法在 gdb 中转储 STL 无序映射容器值 变量类型是 std unordered map var 我的 gdb 版本 7 7 1 GDB配置 configure host x86 64 linux gnu target x86 64
  • 我在使用 ado.net 时收到错误 Argument 2 may not be pass with ref keywords

    int t 0 cmd Parameters AddWithValue Res ref t 我在第二行收到错误 参数 2 不能与 ref 关键字一起传递 您只能通过引用传递参数ref if the 范围 is a ref参数也是如此 Add
  • 如何从外语线程调用Python函数(C++)

    我正在开发一个程序 使用 DirectShow 来抓取音频数据 媒体文件 DirectShow 使用线程将音频数据传递给回调 我的程序中的函数 然后我让该回调函数调用另一个函数 Python 中的函数 我使用 Boost Python 来包
  • C#:自定义转换为值类型

    是否可以将自定义类转换为值类型 这是一个例子 var x new Foo var y int x Does not compile 是否有可能实现上述情况 我需要超载一些东西吗Foo 您将必须重载强制转换运算符 public class F
  • 如何在 C# 中更改公共 IP 地址

    我正在创建一个 C winform 应用程序 我想在其中更改公共 IP 地址 而不是像 Hotspot Shield ZenMate OpenVPN 等那样更改 IPv4 地址 我已经检查了以下链接 但没有找到足够的帮助 所以我发布了这个问
  • 从 DataRow 单元格解析 int [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 如何从 DataRow 单元格解析 int 值 Int32 Parse item QuestionId ToString 这段代码可以工作 但看
  • Gremlin.net 文本包含等效项

    我正在使用 Gremlin net 库连接到 janus 图形服务器 我使用 cassandra 和弹性搜索进行数据存储和索引 在我使用的 gremlin 语言和 gremlin 控制台中文本包含在属性的文本中进行搜索 我正在使用混合索引
  • 如何将System.Windows dll添加到Visual Studio 2010 Express?

    我正在开发一个小型应用程序C and VS2010 as IDE with NET框架4 我想用CaptureSource类以便从笔记本电脑的网络摄像头捕获视频 为此我需要添加一个命名空间System Windows DependencyO
  • “1个未解决的外部”C++

    我已经检查了所有文件之间的连接以及类和函数定义 但每次我尝试运行我的程序时 它都会阻止我并告诉我它有 1 个未解析的外部 该程序应该打开多个文件 一个 学生 文件和一个 成绩 文件 从中读取数据 然后使用 查询文件 来查找数据 找到查询中要
  • 当我的进程被终止时到底会发生什么?

    我有一个包含本机代码和托管代码的混合进程 在 Windows Server 2003 上运行 当我从进程资源管理器中终止进程时 它会进入 100 cpu 的状态 并在消失之前保持这种状态一段时间 有时甚至 10 分钟 在此期间我无法 杀死
  • 实体框架代码首次日期字段创建

    我正在使用实体框架代码优先方法来创建我的数据库表 下面的代码 创建一个DATETIME数据库中的列 但我想创建一个DATE柱子 DataType DataType Date DisplayFormatAttribute ApplyForma

随机推荐

  • 将数据从部分视图提交到控制器 MVC

    我有一个就业记录列表 您还可以使用部分视图从同一页面添加就业记录 这里是雇佣 cshtml 它有一个记录列表的部分视图和一个用于添加出现在模式弹出窗口中的新记录的部分视图 h2 Employment Records h2 Html Rend
  • timedelta64 和日期时间转换

    我的数据框中有两个日期时间 时间戳 格式的列 df start df end 我想知道两个日期之间的持续时间 所以我创建了持续时间列 df duration df start df end 然而 现在duration列的格式为numpy t
  • Xcode 首选项 -> 帐户未保存

    一般在Xcode我们可以在偏好设置中保存不同的苹果帐户 它之前在之前的所有版本中都可以工作 上周我更新了Xcode并安装了Xcode version 10 0然后我添加了 3 4 个 Apple ID Xcode gt 首选项 gt 帐户
  • Swift:多个目标处理:宏不起作用[重复]

    这个问题在这里已经有答案了 从参考如何使用 swift 语言处理 XCode 中的多个目标 and https www appcoda com using xcode targets 我创建了三个目标 每个目标都有不同的包 ID 和应用程序
  • 如何将 Google Mock 与 CppUnitTestFramework 结合使用

    TL DR 您可以使用 GMock 向 Microsoft 本机 C 单元测试添加模拟功能 看我的答案请参阅下文了解详细信息 我想开始向我现有的一组本机单元测试添加模拟 这些测试是使用 Microsoft 编写的CppUnitTestFra
  • PHP pthread 中的对象变量丢失上下文

    我在 PHP 中使用 pthreads 并注意到 pthreads 在其上下文中丢失了对象变量 这是正常的还是错误 或者我做错了什么 class Downloader extends Thread private ch public fun
  • 嵌套函数或方法调用会降低应用程序的性能

    我正在使用 asp net 和 C 开发应用程序 其中我们的项目架构有很多嵌套函数调用 public Employe GetEmployeOrder orderid employe GetEmployeOrderWithDetails or
  • 在 Freemarker 模板中显示 Spring MVC 验证错误

    如果控制器返回绑定错误 我试图在我的 freemarker 模板中显示全局验证错误列表 我可以显示与字段关联的错误 但我想检测特定 bean 中何时发生错误并在页面顶部显示一条消息 我尝试使用下面的示例 但它不产生任何输出 lt sprin
  • Windows 和 Linux 之间的 C++ 可移植性

    我有一个关于编写可在 Windows 和 Linux 之间移植的程序的问题 最近我意识到 如果你编写一个使用任何类型的外部库的程序 如果该库没有 Linux 版本 或者在 Linux 中开发时没有 Windows 版本 那么你就完蛋了 那么
  • 如何使用 .htaccess url 重写添加 .php 扩展名?

    我已经在我的网站上设置了 htaccess 文件 该文件将 SLUG 文本显示为 URL 中的页面名称 但不带扩展名 例如真实网址是 www mywebsite com page php page about us 然后通过url重写加载到
  • 尝试使用 pygame.display.update 在 pygame 中显示 png 文件,它显示不到一秒然后消失。

    图像是一张扑克牌 我们使用的是 pygame 4 5 社区版和 pycharm 2 6 9 因为 2 7 不支持 pygame 这是学校 这是代码 import pygame pygame init picture pygame image
  • Pandas:如何通过以下方式连接数据帧?

    我想将多个数据帧连接成一个数据帧 我希望发生串联的方式如以下示例所示 Input tables A B C D 0 x p 2 4 1 y q 3 5 A B E F 0 x p 6 8 1 y q 9 10 Output table A
  • 如何将文本对象添加到现有的pdf中

    我有一个源 pdf 我正在通过添加文本对象来修改它 我正在使用 PDF 规范中提到的 增量更新 但是 在使用此方法添加文本对象时 我犯了一些错误 导致 pdf 在 Adob e Reader 11 中无法正确呈现 当打开 pdf 并双击它时
  • 将扫描仪类与 GUI 一起使用

    我使用 java swing 创建 GUI 并使用扫描仪类获取从 JTextFields 输入到服务器的信息 这可能吗 如果可能的话怎么办 不 没有控制台 因此不要使用 Scanner 相反 您可以使用 TextField 的 getTex
  • 如何使用 BeginInvoke 从 BackgroundWorker 更新 RichTextBox

    我有一个小应用程序 它读取管道分隔文件并将行写入 RTB 突出显示某些 列 中是否存在不允许的字符 这工作得很好 但是 用户想要一个进度条 并看到 实时 写入的行 并且能够中途取消 我有以下扩展方法 我一直用它来写入 RichTextBox
  • Neo4jClient Cypher 查询的排序顺序不正确

    我有以下 Neo4jClient 代码 var queryItem graphClient Cypher Start new n Node ByIndexLookup myindex Name sku Match p n r Relatio
  • 当 SSRS 中的数据不存在时填充“0”

    我正在尝试在 SSRS 中创建一个报告 其中有一个矩阵 其中性别作为列标题 专门定义的年龄组作为行 该报告按日期排序 即 显示的记录按 modifedAt 值过滤 我的问题是 我希望显示所有年龄组类别 即使数据集不返回该行的任何数据 因此
  • 有没有一个网站可以让我查看不同浏览器支持哪些 HTML 5 标签?还有WebGL?

    我想制作一个 HTML Javascript 网络应用程序 有没有一个网站可以比较哪些浏览器已经支持 HTML5 标签 还有WebGL 是的 有很多 以下是每个人的几个 HTML http a deveria com caniuse HTM
  • 如何查询到Firestore子文档

    我正在开发一个应用程序 我想查询 Firestore 子文档 让我进一步解释一下 我有一组存储汽车的文档 每个文档都有一辆带有描述的特定汽车 在上面的每个文档中 我都有一个名为的子集合user data它有自己的文档 其中存储了将汽车添加到
  • C#.NET 线程问题

    我面临 C NET 应用程序中线程之间通信的问题 希望有人能指导我找到可能的解决方案的正确方向 我有一个 C NET 中的应用程序 它是一个 Windows 窗体应用程序 我的应用程序有两个线程 一个线程是主线程 UI 线程 另一个线程是子