需要击败 GC 并在对象超出范围后将其销毁

2024-01-17

我有几段代码需要用互斥锁来保护。问题是代码看起来像这样:

lock(mylockobject) {
  if(!foo())
    throw new MyException("foo failed");
  if(!bar())
    throw new MyException("bar failed");
}

使用锁,它可以按我想要的方式工作,但现在我需要使用互斥体。这里明显的问题是,如果我获取互斥体并且 foo() 或 bar() 失败,我必须在抛出每个异常之前显式释放互斥体。

在 C++ 中,我将利用在堆栈上创建的对象的范围,并将互斥锁锁定在对象的构造函数中,然后在析构函数中释放它。对于 .NET 的垃圾收集,我认为这行不通。我编写了一个测试应用程序并确认如果我执行以下操作:

public class AutoMutex
{
  private Mutex _mutex;
  public AutoMutex(Mutex mutex)
  {
     _mutex = mutex;
     _mutex.WaitOne();
  }

  ~AutoMutex()
  {
    _mutex.ReleaseMutex();
  }
}

然后有这样的代码:

// some code here...
Mutex my_mutex = new Mutex(false, "MyMutex");
{ // scoping like I would do in C++
  AutoMutex test = new AutoMutex(my_mutex);
  test = null;
}

析构函数(终结器?)直到很久以后才会被调用。

谷歌还没有给我指明正确的方向,但我仍在努力......请让我知道你如何解决这个小问题,如果可能的话。


几点。

1)您要搜索的是“一次性模式”。执行时要非常小心正确地。当然,互斥体already实现了一次性模式,所以我不清楚为什么你想要自己制作,但仍然值得学习。

请参阅此问题,了解有关像 RAII 一样使用一次性模式是否明智的一些其他想法:

使用 IDisposable 和“使用”作为获取“范围行为”以实现异常安全的手段是否滥用? https://stackoverflow.com/questions/2101524

2)Try-finally也有你想要的语义。当然,“using”块只是 try-finally 的语法糖。

3) 你是吗sure当有东西抛出时你想释放互斥体吗?您确定要扔进保护区吗?

由于以下原因,这是一种不好的代码味道。

首先为什么要有互斥体?通常是因为模式是这样的:

  • 状态一致但陈旧
  • 锁定对状态的访问
  • 使状态不一致
  • 使状态一致
  • 解锁对国家的访问
  • 状态现在一致且新鲜

考虑一下在“使状态一致”之前抛出异常时会发生什么。您解锁了对状态的访问,该状态现在不一致且陈旧.

这可能是一个更好的主意保持锁定。是的,这意味着存在死锁的风险,但至少你的程序不会在垃圾、陈旧、不一致的状态下运行。

从锁保护区域内抛出异常是一件非常非常可怕的事情,您应该尽可能避免这样做。从锁内部抛出的异常使您必须在两种可怕的事情之间做出选择:要么陷入死锁,要么当程序操作不一致的状态时出现疯狂的崩溃和不可重现的行为。

您真正应该实现的模式是:

  • 状态一致但陈旧
  • 锁定对状态的访问
  • 使状态不一致
  • 使状态一致
  • 如果发生异常,则回滚到陈旧的一致状态
  • 解锁对国家的访问
  • 状态现在是一致的,如果没有例外,状态是新鲜的

这是更安全的选择,但是编写执行此类事务的代码很困难。没有人说多线程很容易。

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

需要击败 GC 并在对象超出范围后将其销毁 的相关文章

  • 用于代数简化和求解的 C# 库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 网络上有很多代数求解器和简化器 例如 algebra com 上不错的代数求解器和简化器 然而 我正在
  • 在 C++ 中使用 matlab 结构(matlab 函数调用的返回值)(由 matlab 编译器生成的库)

    你好 我有一个相当简单的 matlab 函数 例如 function MYSTRUCT myfunc MYSTRUCT prop1 test MYSTRUCT prop2 foo MYSTRUCT prop3 42 end 我用 matla
  • 确保 StreamReader 不会挂起等待数据

    下面的代码读取从 tcp 客户端流读取的所有内容 并且在下一次迭代中它将仅位于 Read 上 我假设正在等待数据 我如何确保它不会在没有任何内容可供读取时返回 我是否必须设置低超时 并在失败时响应异常 或者有更好的办法吗 TcpClient
  • MVC 在布局代码之前执行视图代码并破坏我的脚本顺序

    我正在尝试将所有 javascript 包含内容移至页面底部 我正在将 MVC 与 Razor 一起使用 我编写了一个辅助方法来注册脚本 它按注册顺序保留脚本 并排除重复的内容 Html RegisterScript scripts som
  • 当我们想要返回对象的引用时,为什么我们在赋值运算符中返回 *this 而通常(而不是 this)?

    我正在学习 C 和指针 我以为我理解了指针 直到我看到这个 一方面 asterix 运算符是解引用的 这意味着它返回值所指向的地址中的值 而与号 运算符则相反 它返回值存储的地址记忆 现在阅读有关赋值重载的内 容 它说 我们返回 this因
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读
  • 为什么 Google 测试会出现段错误?

    我是 Google Test 的新手 正在尝试提供的示例 我的问题是 当我引入失败并设置GTEST BREAK ON FAILURE 1 或使用命令行选项 GTest 将出现段错误 我正在考虑这个例子 https code google c
  • 如何在 32 位或 64 位配置中以编程方式运行任何 CPU .NET 可执行文件?

    我有一个可在 32 位和 64 位处理器上运行的 C 应用程序 我试图枚举给定系统上所有进程的模块 当尝试从 64 位应用程序枚举 32 位进程模块时 这会出现问题 Windows 或 NET 禁止它 我认为如果我可以从应用程序内部重新启动
  • C#:帮助理解 UML 类图中的 <>

    我目前正在做一个项目 我们必须从 UML 图编写代码 我了解 UML 类图的剖析 但我无法理解什么 lt
  • 如何禁用 fread() 中的缓冲?

    我正在使用 fread 和 fwrite 读取和写入套接字 我相信这些函数用于缓冲输入和输出 有什么方法可以在仍然使用这些功能的同时禁用缓冲吗 Edit 我正在构建一个远程桌面应用程序 远程客户端似乎 落后于服务器 我不知道可能是什么原因
  • 外键与独立关系 - Entity Framework 5 有改进吗?

    我读过了several http www ladislavmrnka com 2011 05 foreign key vs independent associations in ef 4 文章和问题 https stackoverflow
  • 动态添加 ASP.Net 控件

    我有一个存储过程 它根据数据库中存储的记录数返回多行 现在我想有一种方法来创建 div 带有包含该行值的控件的标记 如果从数据库返回 10 行 则 10 div 必须创建标签 我有下面的代码来从数据库中获取结果 但我不知道如何从这里继续 S
  • 如何在非控制台应用程序中查看 cout 输出?

    输出到调试窗口似乎相当繁琐 我在哪里可以找到cout如果我正在编写非控制台信息 则输出 Like double i a b cout lt lt b lt lt endl I want to check out whether b is z
  • 使用 C# 读取 Soap 消息

  • 不同类型指针之间的减法[重复]

    这个问题在这里已经有答案了 我试图找到两个变量之间的内存距离 具体来说 我需要找到 char 数组和 int 之间的距离 char data 5 int a 0 printf p n p n data 5 a long int distan
  • 方法优化 - C#

    我开发了一种方法 允许我通过参数传入表 字符串 列数组 字符串 和值数组 对象 然后使用这些参数创建参数化查询 虽然它工作得很好 但代码的长度以及多个 for 循环散发出一种代码味道 特别是我觉得我用来在列和值之间插入逗号的方法可以用不同的
  • C++ 条件编译

    我有以下代码片段 ifdef DO LOG define log p record p else define log p endif void record char data 现在如果我打电话log hello world 在我的代码中
  • Oracle Data Provider for .NET 不支持 Oracle 19.0.48.0.0

    我们刚刚升级到 Oracle 19c 19 3 0 所有应用程序都停止工作并出现以下错误消息 Oracle Data Provider for NET 不支持 Oracle 19 0 48 0 0 我将 Oracle ManagedData
  • 使用 .NET Process.Start 运行时挂起进程 - 出了什么问题?

    我在 svn exe 周围编写了一个快速而肮脏的包装器来检索一些内容并对其执行某些操作 但对于某些输入 它偶尔会重复挂起并且无法完成 例如 一个调用是 svn list svn list http myserver 84 svn Docum
  • 如何将 PostgreSql 与 EntityFramework 6.0.2 集成? [复制]

    这个问题在这里已经有答案了 我收到以下错误 实体框架提供程序类型的 实例 成员 Npgsql NpgsqlServices Npgsql 版本 2 0 14 2 文化 中性 PublicKeyToken 5d8b90d52f46fda7 没

随机推荐

  • 使用前瞻的 C++ std::regex 失败

    我需要从磁盘解析 txt 文件 所以我首先做了一个例子来测试正则表达式 这是我的示例代码 std string txt paragraph r nthis is the text file r ni need only this data
  • 为我的网站创建“徽章”,存储用户徽章的最佳方式?使用PHP

    我正在向我的网站添加 徽章 我想知道存储数据的最佳方式是什么 每个徽章都有一个存储在 MySQL 数据库中的 ID 每个用户在 MySQL 数据库中都有自己的行 并且每个用户都有一个 XML 格式的 userdata 文件 因此 我可以将其
  • SONAR:将此 lambda 替换为方法引用

    Sonar 告诉我 用方法引用替换这个 lambda public class MyClass private List
  • 如何使用 iText 和 Flying Saucer 在从 HTML 创建的 PDF 中嵌入字体?

    我在将波兰语字体嵌入从 HTML 转换为 PDF 时遇到问题 我的 HTML 代码正文有样式 我尝试了两种将此类 HTML 转换为 PDF 的方法 FOP 与 htmlcleaner 带飞碟的 iText 对于 FOP 我可以将所有使用的字
  • 在iOS swift中查看录音?

    是否有任何库可以记录特定的活动UIView 我遇到了这个库 ASScreenRecorder master 但当我尝试在 swift 中使用它或任何其他方式记录时 它显示出许多错误UIView哪个正在显示一些动画 例如飘落的雪花和图像的幻灯
  • Django 中的值相对于前一个值自动递增

    有没有一种方法可以相对于前一个字段自动递增字段 例如 如果前一个记录的值为 09 0001 那么下一个记录应该分配为 09 0002 等等 想法 我正在考虑重写保存方法 但我不太确定到底如何 Django 不允许您在模型中拥有多个 Auto
  • pySpark Columnsimilarities 的问题

    太长了 博士 如何使用 pySpark 比较行的相似度 我有一个 numpy 数组 我想在其中比较每一行之间的相似性 print pdArray 0 1 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 7 5 0 0 0 1 0
  • java 是否缓存方法的结果

    I useJMH指定操作的复杂度 如果您从未与 JMH 合作过 请不要担心 JMH 将刚刚推出estimateOperation方法多次 然后得到平均时间 问题 缩小 这个程序会计算Math cbrt Integer MAX VALUE 每
  • Android MediaPlayer 在某些设备上不播放声音

    我为我的应用程序发出了简单的警报声 但问题是声音在某些设备上播放 而在其他设备上则不播放 示例代码如下 public void audioPlayer leshon tingull kur ka kolision Armando 8 7 2
  • 如何隐藏或加密 JavaScript 代码? [复制]

    这个问题在这里已经有答案了 有没有办法隐藏或加密 JavaScript 代码以防止人们查看 复制和 或修改专有程序 您可以混淆它 但没有办法完全保护它 混淆器示例 https obfuscator io https obfuscator i
  • C# 枚举标志比较

    给定以下标志 Flags public enum Operations add 1 subtract 2 multiply 4 divide 8 eval 16 如何实现 IF 条件来执行每个操作 在我的尝试中 第一个条件适用于添加 评估
  • Office Web 应用程序 - 删除按钮

    有没有办法从 Office Web 应用程序中删除按钮或完整功能区 我想删除下载 添加到一个驱动器等 示例网址如下 https view officeapps live com op view aspx src www cse lehigh
  • jQuery AJAX - 意外的标记 + 解析器错误

    我今天使用 jQuery 和 AJAX 编写了一个脚本 但出现了一些错误 剧本 function changeAdmin id document ready function ta modarea id fadeOut fast ta m
  • 如何按不在数据框中的数组对数据框进行排序

    我已经在不同的上下文中多次回答过这个问题 并且我意识到在任何地方都没有指定好的规范方法 因此 设置一个简单的问题 Problem df pd DataFrame dict A range 6 B 1 2 3 print df A B 0 0
  • Python 在变量后面插入回车符和换行符,而不仅仅是换行符

    我创建了一个 python 脚本来输出 AAAA ZZZZ 等每 1 4 个字符的字母组合 它工作得很好 但是我只需要在打印变量的末尾插入换行符 因为我将其用作要在另一个脚本中使用的单词列表 我尝试同时使用 r 和 n 但是使用 n 在末尾
  • 如何通过简写“if-else”结果来中断循环?

    假设我在循环内有一个简写的 if else 语句 如下例所示 for a b c b c More unnecessary code if the result was true 我想通过条件的结果来打破循环 for a b c b bre
  • iOS 编写宏检测 3.5 英寸或 4 英寸显示器 [重复]

    这个问题在这里已经有答案了 我正在尝试编写一个宏来确定设备是 3 5 英寸还是 4 英寸 下面有一些类似的东西 define IOS OLDER THAN 6 UIDevice currentDevice systemVersion flo
  • Elixir 中的“|>”是什么意思?

    我正在阅读 github 上的一些 Elixir 代码 我发现 gt 经常被使用 它没有出现在列表中手术 http elixir lang org getting started basic operators html在文档网站上 这是什
  • 如何将 HTML 输入类型属性从“密码”更改为“文本”?

    我想更改 HTML input 元素 type 属性 从 type password 更改为 type text 我知道通过 ID 查找元素会更容易 但并非每个页面都有相同的密码输入 ID 如何定位密码输入并将其内部值更改为文本类型 我有这
  • 需要击败 GC 并在对象超出范围后将其销毁

    我有几段代码需要用互斥锁来保护 问题是代码看起来像这样 lock mylockobject if foo throw new MyException foo failed if bar throw new MyException bar f