线程池 - 可能的线程执行顺序问题

2023-12-19

我一直在学习如何使用线程池,但我不确定池中的每个线程是否都正确执行,并且我怀疑有些线程被执行多次。我已将代码削减到最低限度,并一直使用 Debug.WriteLine 来尝试弄清楚发生了什么,但这会产生一些奇怪的结果。

我的代码如下(基于(不支持 STA 线程上多个句柄的 WaitAll https://stackoverflow.com/questions/4192834/waitall-for-multiple-handles-on-a-sta-thread-is-not-supported):

public void ThreadCheck()
    {
        string[] files;
        classImport Import;
        CountdownEvent done = new CountdownEvent(1);
        ManualResetEvent[] doneEvents = new ManualResetEvent[10];

        try
        {
            files = Directory.GetFiles(importDirectory, "*.ZIP");

            for (int j = 0; j < doneEvents.Length; j++)
            {
                done.AddCount();
                Import = new classImport(j, files[j], workingDirectory + @"\" + j.ToString(), doneEvents[j]);
                ThreadPool.QueueUserWorkItem(
                (state) =>
                {
                    try
                    {
                        Import.ThreadPoolCallBack(state);
                        Debug.WriteLine("Thread " + j.ToString() + " started");
                    }
                    finally
                    {
                        done.Signal();
                    }
                }, j);

            }

            done.Signal();
            done.Wait();                            
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Error in ThreadCheck():\n" + ex.ToString());
        }
    }

classImport.ThreadPoolCallBack 目前实际上没有执行任何操作。

如果我手动单步执行代码,我会得到:

线程 1 已启动 线程 2 已启动 ....一路到.... 线程 10 已启动

但是,如果我手动运行它,输出窗口将填充“线程 10 已启动”

我的问题是:我使用线程池的代码是否有问题,或者 Debug.WriteLine 的结果是否被多个线程混淆了?


问题是您正在使用循环变量(j) 在 lambda 表达式中。

为什么这是一个问题的细节相当冗长 - 请参阅埃里克·利珀特的博客文章 http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx有关详细信息(另请阅读part 2 http://blogs.msdn.com/b/ericlippert/archive/2009/11/16/closing-over-the-loop-variable-part-two.aspx).

幸运的是,修复很简单:只需创建一个新的局部变量inside循环并在 lambda 表达式中使用它:

for (int j = 0; j < doneEvents.Length; j++)
{
    int localCopyOfJ = j;

    ... use localCopyOfJ within the lambda ...
}

对于循环体的其余部分,只需使用即可j- 只有当它被 lambda 表达式或匿名方法捕获时,它才会成为问题。

这是一个困扰很多人的常见问题 - C# 团队已经考虑更改foreach循环(其中really看起来您已经在每次迭代中声明了一个单独的变量),但这会导致有趣的兼容性问题。 (例如,您可以编写运行良好的 C# 5 代码,而使用 C# 4 可能可以很好地编译,但实际上会被破坏。)

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

线程池 - 可能的线程执行顺序问题 的相关文章

  • std::cout 和 std::wcout 有什么区别?

    在c 中 有什么区别std cout and std wcout 它们都控制流缓冲区的输出或将内容打印到控制台 或者它们只是相似吗 它们作用于不同的字符类型 std cout uses char作为字符类型 std wcout uses w
  • C++ 中本地类中的静态成员变量?

    我知道我们不能宣布static本地类中的成员变量 但其原因尚不清楚 那么请问有人可以解释一下吗 另外 为什么我们不能访问非static函数内部定义的变量 内部已经定义了局部类 直接在局部类成员函数中 在下面给出的代码中 int main i
  • Unix网络编程澄清

    我正在翻阅这本经典书籍Unix网络编程 https rads stackoverflow com amzn click com 0139498761 当我偶然发现这个程序时 第 6 8 节 第 179 180 页 include unp h
  • 向 Nhibernate 发出 SQL 查询

    如何将此 SQL 查询发送给 Nhibernate SELECT Customer name FROM Company INNER JOIN Customer ON Company CompanyId Customer CompanyId
  • 为什么下面代码的输出是Thread[main,5,main]

    public class test1 public static void main String args TODO Auto generated method stub Thread t Thread currentThread Sys
  • 读取文件特定行号的有效方法。 (奖励:Python 手册印刷错误)

    我有一个 100 GB 的文本文件 它是来自数据库的 BCP 转储 当我尝试导入它时BULK INSERT 我在第 219506324 行上收到一个神秘错误 在解决此问题之前 我想看看这一行 但可惜的是我最喜欢的方法 import line
  • C# Dns.GetHostEntry 不返回连接到 WiFi 的移动设备的名称

    我有一个 C 中的 Windows 窗体应用程序 我试图获取列表中所有客户端的主机名 下面给出的是 ra00l 来自此链接的代码示例 GetHostEntry 非常慢 https stackoverflow com questions 99
  • 如何在 C# 中定义文本框数组?

    您好 当我在 Windows 申请表上创建文本框时 我无法将其命名为 box 0 box 1 等 我这样做的目的是因为我想循环使用它们 其实我发现TextBox array firstTextBox secondTextBox 也有效
  • 使用 JNI 从 Java 代码中检索 String 值的内存泄漏

    我使用 GetStringUTFChars 从使用 JNI 的 java 代码中检索字符串的值 并使用 ReleaseStringUTFChars 释放该字符串 当代码在 JRE 1 4 上运行时 不会出现内存泄漏 但如果相同的代码在 JR
  • 如何将整数转换为 void 指针?

    在 C 中使用线程时 我面临警告 警告 从不同大小的整数转换为指针 代码如下 include
  • 上下文敏感与歧义

    我对上下文敏感性和歧义如何相互影响感到困惑 我认为正确的是 歧义 歧义语法会导致使用左推导或右推导构建多个解析树 所有可能的语法都是二义性的语言是二义性语言 例如 C 是一种不明确的语言 因为 x y 总是可以表示两个不同的事物 如下所述
  • 如何在 Blackberry Cascades 中显示具有特定号码的电话板

    我正在使用带有 C QT 和 QML 的 Blackberry Cascades 10 Beta 3 SDK 以及 Blackberry 10 Dev Alpha Simulator 和 QNX Momentics IDE 并且我正在尝试实
  • 如何对 Web Api 操作进行后调用?

    我创建了一个 Web API 操作 如下所示 HttpPost public void Load string siteName string providerName UserDetails userDetails implementat
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • Server.MapPath - 给定的物理路径,预期的虚拟路径

    我正在使用这行代码 var files Directory GetFiles Server MapPath E ftproot sales 在文件夹中查找文件 但是我收到错误消息说 给定物理路径但虚拟路径 预期的 我对在 C 中使用 Sys
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • 使用 GROUP 和 SUM 的 LINQ 查询

    请帮助我了解如何使用带有 GROUP 和 SUM 的 LINQ 进行查询 Query the database IEnumerable
  • 使用 GhostScript.NET 打印 PDF DPI 打印问题

    我在用GhostScript NET http ghostscriptnet codeplex com打印 PDF 当我以 96DPI 打印时 PDF 打印效果很好 但有点模糊 如果我尝试以 600DPI 打印文档 打印的页面会被极大地放大
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了

随机推荐

  • Ruby 单元测试:在每次失败的测试后运行一些代码

    在 ruby 单元测试中断言失败后 是否有一些干净而优雅的方法可以立即执行我的代码Test Unit 前teardown被处决 我正在做一些自动化 GUI 测试 并且想在出现故障后立即截取屏幕截图 如果您使用的是 1 9 请不要使用 Tes
  • 如何在 C# 中与 Windows Media Player 交互

    我正在寻找一种与独立完整版 Windows Media Player 进行交互的方法 大多数情况下 我需要知道当前播放曲目的路径 iTunes SDK 使这一切变得非常简单 但不幸的是 确实没有任何方法可以使用 Windows Media
  • C# 函数是否有标准的“永不返回”属性?

    我有一种方法 如下所示 void throwException string msg throw new MyException msg 现在如果我写 int foo int x y if y 0 throwException Doh el
  • Spinner 作为 MenuItem 未由 findViewById 初始化

    我的操作栏上有一个微调器 它是一个菜单项 不是导航模式 它在我从 spinnerNumber 调用方法的行返回一个 nullpointerException 我认为我对 xml 做了一些错误 或者也许我不应该在 OnCreateOption
  • 从 Julia 1.0 中特定目录中的文件导入模块和函数

    假设我有一个文件File jl有一个模块MyModule包含函数foo and bar在里面 在与模块文件相同的目录中 我有一个脚本Script jl 我想使用其中的函数MyModule在脚本中 人们会如何去做这件事呢 为了找到不在标准 L
  • 无法在 ROS 中使用本地安装的 Protocol Buffer

    我已经安装了协议缓冲区 https developers google com protocol buffers 本地 ROS包的目录结构如下 CMakeLists txt package xml include addressbook p
  • 进行更改后 ts-node-dev 不会重新启动

    这是我的文件 包 json scripts generate interfaces ts node src cli generate interfaces ts dist npm run generate interfaces rm rf
  • Google Play 服务示例:“connectionResult 无法解析”

    当我尝试按照有关如何检查 Google Play 服务是否已安装的示例进行操作时 我收到以下错误 servicesConnected 方法内的行中的 connectionResult 无法解析 int errorCode connectio
  • 片段replace()不替换所有片段

    如果我为具有相同 viewId 的片段 A 和 B 调用 add 然后尝试使用片段 C 在该 viewId 上调用 Replace 则只有片段 A 被删除 最终得到片段 B 和 C 根据文档 A 和 B 都应该替换为 C 或者我读错了文档
  • XC8 收到有关 plib I2C 函数的“未定义符号”错误

    嘿 StackOverflow 我的问题涉及下面粘贴的程序中报告的错误 目标设备是PIC12LF1552 它有一个串行外设 我认为它可以与 Microchip 的 XC8 编译器提供的库结合使用 互联网上的一些消息来源表示 只有 PIC18
  • 增强序列化和双打

    我正在尝试使用 boost 序列化库将类序列化为字符串 并且我的类中包含几个双成员变量 下面是我用来序列化的代码 include
  • Java中如何对泛型类型设置约束?

    我有一个通用类 public class ListObject
  • 如何在C++中获取外部IP地址?

    我将如何在 C 中查找用户的外部 IP 我需要一种适用于任何系统的方法 而不仅仅是我的系统 此外 系统可能位于路由器后面 因此 NAT 将发挥作用 从而使检索外部 IP 变得更加困难 理想情况下 我希望在不使用任何第三方服务 例如whats
  • 如何使用 zip cmd 工具将文件移至未压缩的 zip 中

    我试图确定如何使用zipcmd 行工具将文件 未压缩 移动到压缩文件的 zip 中 即我想要一个 zip 最后包含除一个压缩文件之外的所有文件 b c 该一个文件是另一个压缩文件 有人知道怎么做吗 看起来您可以使用 n 选项仅存储具有定义扩
  • 有没有办法确定 Linux PID 是否暂停?

    我有一个 python 脚本 它使用 SIGSTOP 和 SIGCONT 命令与 os kill 来暂停或恢复进程 有没有办法判断相关PID是处于暂停状态还是恢复状态 您可以从进程的 proc 目录 proc
  • 基于工作流(即有向图)浏览器的编辑器

    我想提供一个所见即所得的工具 最好是基于 JavaScript 的 用于工作流程图 即有向图 我需要商业软件友好许可 其中可能包括向 OEM 支付费用 如果有必要的服务器端部分 我需要 Java 或 ColdFusion 中的它 因为我正在
  • 如何从 Entity Framework 4.3 升级到 EF 5

    目前我们正在开发 EF 4 3 我们想将其升级到 EF5 我用谷歌搜索了升级过程步骤 但没有得到任何结果 请帮我 谢谢 以下是我在 EF4 3 到 EF5 上创建的内容的两个链接 文章 将现有项目迁移到 EF 5http msdn micr
  • Hibernate:在级联删除项目时清理集合的二级缓存

    我有一个问题 Hibernate 不会为级联删除的项目集合更新二级缓存 Details 假设我们有一个对象 Parent 其中包含 Child 对象的 Parent myChildren 集合 现在我们还有 Humans 对象和 Human
  • 计算我的位置与 Swift 上的 MapKit 图钉之间的距离

    我需要你的帮助 我正在开发一个应用程序 其中有一些图钉 位置 我想要的是获取每个图钉与我的位置之间的距离 我的代码如下 let annotation MKPointAnnotation let annotationTwo MKPointAn
  • 线程池 - 可能的线程执行顺序问题

    我一直在学习如何使用线程池 但我不确定池中的每个线程是否都正确执行 并且我怀疑有些线程被执行多次 我已将代码削减到最低限度 并一直使用 Debug WriteLine 来尝试弄清楚发生了什么 但这会产生一些奇怪的结果 我的代码如下 基于 不