如何在.NET 中编写安全/正确的多线程代码?

2024-05-13

今天我必须修复一些使用线程的旧 VB.NET 1.0 代码。问题在于从工作线程而不是 UI 线程更新 UI 元素。我花了一些时间才发现可以使用 InvokeRequired 断言来查找问题。

除了上面提到的并发修改问题之外,还可能遇到死锁、竞争条件等问题。由于调试/修复线程问题很痛苦,我想知道如何减少该领域的编码错误/故障以及如何更轻松地找到其中的任何错误/故障。所以,我要求的是:

  • 编写多线程代码时有什么好的模式可以遵循吗?什么是该做和不该做的事情?
  • 您使用什么技术来调试线程问题?

如果适用且可能,请提供一些示例代码。答案应该与 .NET 框架(任何版本)相关。


这可能是一个massive列表 - 阅读 Joe Duffy 的优秀作品“Windows 上的并发编程 https://rads.stackoverflow.com/amzn/click/com/032143482X“了解更多细节。这几乎是一个大脑垃圾场......

  • 当您拥有锁时,尽量避免调用大量代码
  • 避免锁定类外部代码也可能锁定的引用
  • 如果您需要一次获取多个锁,请始终以相同的顺序获取这些锁
  • 在合理的情况下,使用不可变类型 - 它们可以在线程之间自由共享
  • 除了不可变类型之外,尽量避免在线程之间共享数据
  • 避免尝试使您的类型线程安全;大多数类型不需要,通常需要共享数据的代码需要控制锁定本身
  • In a WinForms app:
    • 不要在 UI 线程上执行任何长时间运行或阻塞的操作
    • 不要从 UI 线程以外的任何线程接触 UI。 (使用BackgroundWorker、Control.Invoke/BeginInvoke)
  • 尽可能避免线程局部变量(又名线程静态) - 它们可能会导致意外行为,特别是在 ASP.NET 上,其中请求可能由不同线程提供服务(搜索“线程敏捷性”和 ASP.NET)
  • 不要试图表现得聪明。无锁并发代码是hugely很难做对。
  • 记录您的类型的线程模型(和线程安全)
  • Monitor.Wait 几乎总是应该在 while 循环中与某种检查结合使用(即 while (I can't continue) Monitor.Wait(monitor))
  • 每次使用 Monitor.Pulse 和 Monitor.PulseAll 之一时,请仔细考虑它们之间的区别。
  • 插入 Thread.Sleep 来解决问题从来都不是真正的解决办法。
  • 查看“并行扩展”和“协调和并发运行时”作为使并发更简单的方法。并行扩展将成为 .NET 4.0 的一部分。

在调试方面,我没有太多建议。使用 Thread.Sleep 来增加出现竞争条件和死锁的机会是可行的,但在知道将问题放在哪里之前,您必须对问题有一个相当合理的理解。日志记录非常方便,但不要忘记代码会进入某种量子状态 - 通过日志记录观察它几乎必然会改变其行为!

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

如何在.NET 中编写安全/正确的多线程代码? 的相关文章

  • C# 中的 Stack<> 实现

    我最近一直在实现递归目录搜索实现 并且使用堆栈来跟踪路径元素 当我使用 string Join 连接路径元素时 我发现它们被颠倒了 当我调试该方法时 我查看了堆栈 发现堆栈内部数组中的元素本身是相反的 即最近 Push 的元素位于内部数组的
  • 无法继承形状

    为什么我不能使用继承 a 的类Shapes class http msdn microsoft com en us library ms604615 28v vs 90 29 我需要延长Rectangle具有一些方法的类 但我想以与使用相同
  • 在 C++ 代码中转换字符串

    我正在学习 C 并开发一个项目来练习 但现在我想在代码中转换一个变量 字符串 就像这样 用户有一个包含 C 代码的文件 但我希望我的程序读取该文件并插入将其写入代码中 如下所示 include
  • 在 Mono 中反序列化 JSON 数据

    使用 Monodroid 时 是否有一种简单的方法可以将简单的 JSON 字符串反序列化为 NET 对象 System Json 只提供序列化 不提供反序列化 我尝试过的各种第三方库都会导致 Mono Monodroid 出现问题 谢谢 f
  • C# 中一次性对象克隆会导致内存泄漏吗?

    检查这个代码 class someclass IDisposable private Bitmap imageObject public void ImageCrop int X int Y int W int H imageObject
  • Makefile 和 .Mak 文件 + CodeBlocks 和 VStudio

    我对整个 makefile 概念有点陌生 所以我对此有一些疑问 我正在 Linux 中使用 CodeBlocks 创建一个项目 我使用一个名为 cbp2mak 的工具从 CodeBlocks 项目创建一个 make 文件 如果有人知道更好的
  • 包恢复失败。回滚包更改 - Serilog.AspNetCore

    我有一个 asp net Core 项目 我正在尝试向其中添加一个记录器 我选择了我在其他项目中使用过的 SeriLog 但是当我尝试添加 Serilog AspNetCore 我得到的软件包版本 2 0 0 包恢复失败 回滚 后端 的包更
  • JavaScript 错误:MVC2 视图中的条件编译已关闭

    我试图在 MVC2 视图页面中单击时调用 JavaScript 函数 a href Select a JavaScript 函数 function SelectBenefit id code alert id alert code 这里 b
  • C# 根据当前日期传递日期时间值

    我正在尝试根据 sql server 中的两个日期获取记录 Select from table where CreatedDate between StartDate and EndDate我通过了5 12 2010 and 5 12 20
  • LinkLabel 无下划线 - Compact Framework

    我正在使用 Microsoft Compact Framework 开发 Windows CE 应用程序 我必须使用 LinkLabel 它必须是白色且没有下划线 因此 在设计器中 我将字体颜色修改为白色 并在字体对话框中取消选中 下划线
  • C# 获取数据表中所有重复行的计数

    我通过运行存储过程来填充数据集 并且从数据集中填充数据表 DataSet RawDataSet DataAccessHelper RunProcedure storedprocedureName this will just return
  • 让网络摄像头在 OpenCV 中工作

    我正在尝试让我的网络摄像头在 Windows 7 64 位中的 OpenCV 版本 2 2 中捕获视频 但是 我遇到了一些困难 OpenCV 附带的示例二进制文件都无法检测到我的网络摄像头 最近我发现这篇文章表明答案在于重新编译一个文件 o
  • 对于 C# Express 用户来说,有哪些好的工具可以识别可能重复的代码? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 也可以看看 有什么工具可以检查重复的 VB NET 代码吗 https stackoverflow c
  • MySQL 连接器 C++ 64 位在 Visual Studio 2012 中从源代码构建

    我正在尝试建立mySQL 连接器 C 从源头在视觉工作室2012为了64 bit建筑学 我知道这取决于一些boost头文件和C 连接器 跑步CMake生成一个项目文件 但该项目文件无法编译 因为有一大堆非常令人困惑的错误 这些错误可能与包含
  • ASP.NET Core 中间件与过滤器

    在阅读了 ASP NET Core 中间件之后 我对何时应该使用过滤器以及何时应该使用中间件感到困惑 因为它们似乎实现了相同的目标 什么时候应该使用中间件而不是过滤器 9频道有一个关于此的视频 ASP NET 怪物 91 中间件与过滤器 h
  • .NET 和 Mono 之间的开发差异

    我正在研究 Mono 和 NET C 将来当项目开发时我们需要在 Linux 服务器上运行代码 此时我一直在研究 ASP NET MVC 和 Mono 我运行 Ubuntu 发行版 想要开发 Web 应用程序 其他一些开发人员使用 Wind
  • Unity3D - 将 UI 对象移动到屏幕中心,同时保持其父子关系

    我有一个 UI 图像 它的父级是 RectTransform 容器 该容器的父级是 UI 面板 而 UI 面板的父级是 Canvas 我希望能够将此 UI 图像移动到屏幕中心 即画布 同时保留父级层次结构 我的目标是将 UI 图像从中心动画
  • C:设置变量范围内所有位的最有效方法

    让我们来int举个例子 int SetBitWithinRange const unsigned from const unsigned to To be implemented SetBitWithinRange应该返回一个int其中所有
  • 如果将变量设置为等于新对象,旧对象会发生什么?

    假设我们有一个 X 类not有一个超载的operator 功能 class X int n X n 0 X int n n n int main X a 1 an object gets constructed here more code
  • 如果找不到指定的图像文件,显示默认图像的最佳方式?

    我有一个普通的电子商务应用程序 我将 ITEM IMAGE NAME 存储在数据库中 有时经理会拼错图像名称 为了避免 丢失图像 IE 中的红色 X 每次显示产品列表时 我都会检查服务器中是否有与该产品相关的图像 如果该文件不存在 我会将其

随机推荐