废弃的命名信号量未释放

2023-11-24

当 C# 程序持有命名信号量时,当应用程序提前终止(例如按 Ctrl+C 或关闭控制台窗口)时,它似乎不会被释放。至少在该进程的所有实例都终止之前不会。

对于命名互斥体,在这种情况下会引发 AbandonedMutexException,但对于信号量则不会。当另一个程序实例提前终止时,如何防止一个程序实例停止运行?

class Program
{
    // Same with count > 1
    private static Semaphore mySemaphore = new Semaphore(1, 1, "SemaphoreTest");

    static void Main(string[] args)
    {
        try
        {
            // Blocks forever if the first process was terminated
            // before it had the chance to call Release
            Console.WriteLine("Getting semaphore");
            mySemaphore.WaitOne();  
            Console.WriteLine("Acquired...");
        }
        catch (AbandonedMutexException)
        {
            // Never called!
            Console.WriteLine("Acquired due to AbandonedMutexException...");
        }
        catch (System.Exception ex)
        {
            Console.WriteLine(ex);
        }

        Thread.Sleep(20 * 1000);
        mySemaphore.Release();
        Console.WriteLine("Done");
    }
}

一般来说,你can't保证线程退出时释放信号量。您可以编写 try/finally 块和关键终结器,但如果程序异常终止,这些并不总是有效。而且,与互斥体不同,如果线程在仍持有信号量时退出,则不会通知其他线程。

原因是,Windows 信号量对象.NET Semaphore 对象所基于的,不会跟踪哪些线程已获取它,因此不能抛出类似于AbandonedMutexException.

也就是说,你can当用户关闭窗口时收到通知。您需要设置一个控制处理程序来侦听特定事件。您调用 Windows API 函数设置ConsoleCtrlHandler,向其传递一个处理您感兴趣的事件的回调函数(委托)。我这样做已经有一段时间了,但总的来说。

为以下内容创建一个托管原型SetConsoleCtrlHandler函数和回调:

/// <summary>
/// Control signals received by the console control handler.
/// </summary>
public enum ConsoleControlEventType: int
{
    /// <summary>
    /// A CTRL+C signal was received, either from keyboard input or from a
    /// signal generated by the GenerateConsoleCtrlEvent function.
    /// </summary>
    CtrlC = 0,
    /// <summary>
    /// A CTRL+BREAK signal was received, either from keyboard input or from
    /// a signal generated by GenerateConsoleCtrlEvent.
    /// </summary>
    CtrlBreak = 1,
    /// <summary>
    /// A signal that the system sends to all processes attached to a console
    /// when the user closes the console (either by clicking Close on the console
    /// window's window menu, or by clicking the End Task button command from
    /// Task Manager).
    /// </summary>
    CtrlClose = 2,
    // 3 and 4 are reserved, per WinCon.h
    /// <summary>
    /// A signal that the system sends to all console processes when a user is logging off. 
    /// </summary>
    CtrlLogoff = 5,
    /// <summary>
    /// A signal that the system sends to all console processes when the system is shutting down. 
    /// </summary>
    CtrlShutdown = 6
}

/// <summary>
/// Control event handler delegate.
/// </summary>
/// <param name="CtrlType">Control event type.</param>
/// <returns>Return true to cancel the control event.  A return value of false
/// will terminate the application and send the event to the next control
/// handler.</returns>
public delegate bool ConsoleCtrlHandlerDelegate(ConsoleControlEventType CtrlType);

[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool SetConsoleCtrlHandler(
ConsoleCtrlHandlerDelegate HandlerRoutine,
bool Add);

现在,创建您的处理程序方法:

private static bool ConsoleCtrlHandler(ConsoleControlEventType CtrlType)
{
    switch (CtrlType)
    {
        case CtrlClose:
            // handle it here
            break;
        case CtrlBreak:
            // handle it here
            break;
    }
    // returning false ends up calling the next handler
    // returning true will prevent further handlers from being called.
    return false;
}

最后,在初始化期间您要设置控制处理程序:

SetConsoleCtrlHandler(ConsoleControlHandler);

现在,当用户关闭窗口时,将调用您的控制处理程序。这将允许您释放信号量或进行其他清理。

您可能对我的感兴趣控制台DotNet包。我写了三篇关于这些内容的文章,其中最后两篇仍然可以在 DevSource 上找到。我不知道第一个发生了什么。

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

废弃的命名信号量未释放 的相关文章

  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • fgets() 和 Ctrl+D,三次才能结束?

    I don t understand why I need press Ctrl D for three times to send the EOF In addition if I press Enter then it only too
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • 为什么 POSIX 允许在只读模式下超出现有文件结尾 (fseek) 进行搜索

    为什么寻找文件结尾很有用 为什么 POSIX 让我们像示例中那样在以只读方式打开的文件中进行查找 c http en cppreference com w c io fseek http en cppreference com w c io
  • 使用 Google Analytics API 在 C# 中显示信息

    我一整天都在寻找一个好的解决方案 但谷歌发展得太快了 我找不到有效的解决方案 我想做的是 我有一个 Web 应用程序 它有一个管理部分 用户需要登录才能查看信息 在本节中 我想显示来自 GA 的一些数据 例如某些特定网址的综合浏览量 因为我
  • C# 用数组封送结构体

    假设我有一个类似于 public struct MyStruct public float a 我想用一些自定义数组大小实例化一个这样的结构 在本例中假设为 2 然后我将其封送到字节数组中 MyStruct s new MyStruct s
  • HttpClient 像浏览器一样请求

    当我通过 HttpClient 类调用网站 www livescore com 时 我总是收到错误 500 可能服务器阻止了来自 HttpClient 的请求 1 还有其他方法可以从网页获取html吗 2 如何设置标题来获取html内容 当
  • 基于范围的 for 循环中的未命名循环变量?

    有没有什么方法可以不在基于范围的 for 循环中 使用 循环变量 同时也避免编译器发出有关未使用它的警告 对于上下文 我正在尝试执行以下操作 我启用了 将警告视为错误 并且我不想进行像通过在某处毫无意义地提及变量来强制 使用 变量这样的黑客
  • 按字典顺序对整数数组进行排序 C++

    我想按字典顺序对一个大整数数组 例如 100 万个元素 进行排序 Example input 100 21 22 99 1 927 sorted 1 100 21 22 927 99 我用最简单的方法做到了 将所有数字转换为字符串 非常昂贵
  • A* 之间的差异 pA = 新 A;和 A* pA = 新 A();

    在 C 中 以下两个动态对象创建之间的确切区别是什么 A pA new A A pA new A 我做了一些测试 但似乎在这两种情况下 都调用了默认构造函数 并且仅调用了它 我正在寻找性能方面的任何差异 Thanks If A是 POD 类
  • 使用向量的 merge_sort 在少于 9 个输入的情况下效果很好

    不知何故 我使用向量实现了合并排序 问题是 它可以在少于 9 个输入的情况下正常工作 但在有 9 个或更多输入的情况下 它会执行一些我不明白的操作 如下所示 Input 5 4 3 2 1 6 5 4 3 2 1 9 8 7 6 5 4 3
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • 更改窗口的内容 (WPF)

    我创建了一个简单的 WPF 应用程序 它有两个 Windows 用户在第一个窗口中填写一些信息 然后单击 确定 这会将他们带到第二个窗口 这工作正常 但我试图将两个窗口合并到一个窗口中 这样只是内容发生了变化 我设法找到了这个更改窗口内容时
  • AccessViolationException 未处理

    我正在尝试使用史蒂夫 桑德森的博客文章 http blog stevensanderson com 2010 01 28 editing a variable length list aspnet mvc 2 style 为了在我的 ASP
  • 将日期参数传递给对 MVC 操作的 ajax 调用的安全方法

    我有一个 MVC 操作 它的参数之一是DateTime如果我通过 17 07 2012 它会抛出一个异常 指出参数为空但不能有空值 但如果我通过01 07 2012它被解析为Jan 07 2012 我将日期传递给 ajax 调用DD MM
  • 如何在.NET Core上直接调用F#编译器?

    UPD 我想直接从 NET Core SDK 调用 F 编译器 即 fsc 我了解 dotnet build co 但当我只需要编译一个简单的问题时 即 fsc file fs 就足够的情况下 我不想涉及它们 我尝试在 NET Core S
  • ListDictionary 类是否有通用替代方案?

    我正在查看一些示例代码 其中他们使用了ListDictionary对象来存储少量数据 大约 5 10 个对象左右 但这个数字可能会随着时间的推移而改变 我使用此类的唯一问题是 与我所做的其他所有事情不同 它不是通用的 这意味着 如果我在这里
  • C++ 成员函数中的“if (!this)”有多糟糕?

    如果我遇到旧代码if this return 在应用程序中 这种风险有多严重 它是一个危险的定时炸弹 需要立即在应用程序范围内进行搜索和销毁工作 还是更像是一种可以悄悄留在原处的代码气味 我不打算writing当然 执行此操作的代码 相反
  • 为什么 strtok 会导致分段错误?

    为什么下面的代码给出了Seg 最后一行有问题吗 char m ReadName printf nRead String s n m Writes OK char token token strtok m 如前所述 读取字符串打印没有问题 但

随机推荐

  • iOS Safari 和 Chrome 上的 Z 索引问题

    我遇到了基于 wordpress Underscores 主题的响应式下拉菜单的问题 它在桌面上看起来不错 但在 iOS Safari 上 包括 iPad 和 iPhone 则不然 我也尝试将 z index 添加到其他 div 但它不起作
  • Ajax 文件上传,“进度”上传事件在 Edge 浏览器中不会触发

    我正在开发一个文件上传控件 通过 ajax 发布表单数据 我在 Chrome Firefox IE 11 10 中可以使用此跨浏览器 但是在 Microsoft Edge 浏览器中 上传 进度 事件似乎不会触发 谁能指出原因并告诉我 Edg
  • make -j 8 g++:内部编译器错误:已杀死(程序 cc1plus)

    当我在 Ubuntu12 04 上部署 Apache Mesos 时 我按照官方文档进行操作 在步骤 make j 8 中 我在控制台中收到此错误 g internal compiler error Killed program cc1pl
  • 左外连接和右外连接哪个更好?

    我们可以通过这两种方式得到相同的结果 Table 1 LEFT OUTER JOIN Table 2 Table 2 RIGHT OUTER JOIN Table 1 如果我们能得到相同的结果为什么要使用右外连接 哪一个更好 正如其他人已经
  • pdfBox - 签名有效性复选标记在 Acrobat reader 中不可见

    我正在使用此作为参考向 pdf 添加视觉签名 https stackoverflow com a 27940667 7103795 我能够正确打印详细信息 但在 Acrobat 中打开 pdf 时 它不会显示绿色勾号 尽管它写着 已签名且所
  • 如何在 Quill 编辑器中预填充 http 链接?

    使用 Quill 编辑器添加链接时 我必须包含协议 否则链接将被视为相对链接 当有人单击添加链接时 我希望该字段预先填充http 所以当用户输入google com它将创建一个链接到http google com代替http myapp n
  • Apache VirtualHost 403 禁止

    我最近尝试使用 Apache 设置测试服务器 该网站必须在域下运行www mytest com 我总是得到一个403 Forbidden错误 我使用的是 Ubuntu 10 10 服务器版本 文档根目录位于 dir 下 var www 以下
  • 如何使用msbuild创建nuget包而不重建项目?

    我想设置一个包含构建 测试和部署阶段的 CI CD 管道 我可以在构建阶段构建我的项目 msbuild src MyProject csproj t Restore msbuild src MyProject csproj p Config
  • 尝试导入错误:“firebase/app”不包含默认导出(导入为“firebase”)

    我尝试使用 React 进行 firebase 身份验证 但它显示错误 Attempted import error firebase app does not contain a default export imported as fi
  • gpus_ReturnGuiltyForHardwareRestart 崩溃

    应用程序在presentFrameBuffer中崩溃 在前台运行时 没有发生中断 它没有在第一帧中崩溃 它绘制了一段时间然后突然崩溃 我没有具体的重现步骤 但似乎与绘制特定的内容有关 但我仍然没有通过应用程序报告 openGL 错误 包括在
  • x86 BSWAP 指令 REX 不遵循 Intel 规范?

    我一直在使用 NASM 和 GAS 汇编 和反汇编 BSWAP x64 指令 并且都汇编指令BSWAP r15 as 490FCF以十六进制表示 反汇编器也将其反汇编为相同的指令 指令的 REX 前缀 49 因此设置了 REX W 位 位
  • 导出到 Excel 时,SSRS 不支持 CanGrow 属性

    我在 SSRS 报告中有一个表 表格单元之一包含订单中零件的描述 这些描述的长度可能会有所不同 因此我将 CanGrow 属性设置为 True 当我尝试将报告导出到 Excel 时 我希望如果文本长度超过单元格的宽度 那么单元格的高度将会增
  • $(window) 绑定 hashchange 如何检查部分哈希更改?

    我在学习Google Ajax Crawlable I use window bind hashchange控制ajax页面加载 我的网址如下 domain com keywords num 1 有两种改变 domain com apple
  • 在 OpenGLES 中让精灵正确面对相机

    我有一款或多或少是 2D 的游戏 但以 3D 渲染 摄像机悬停在 2D 游戏场上方 与完全垂直的角度倾斜约 20 度 从而为其提供一点 3D 视角 我有一些精灵需要渲染为完美的正方形 因为它们代表球形物体 我的第一种方法将四边形渲染在 2D
  • STL - 以下代码有什么问题?

    include stdafx h include
  • PDF 到 Github 风格的 Markdown

    我有一个 PDF 格式的项目描述 如果我能以某种方式设法在 github 网站上预览它 而不是单击 查看原始数据 并下载它 我会非常高兴 我以为可能有一个从 pdf 到 github 风格的 markdown 的转换器 但没有找到 再次声明
  • 字典应用程序的数据库设计

    目前我想开发移动设备的词典应用程序 词典本身使用离线文件 数据库来翻译单词 它只翻译两种语言 例如英语 西班牙语词典 我脑子里有一个简单的设计 这将是两个表 英语表和西班牙语表 每个表包含 word id id 它将作为其他表的外键 词 词
  • 重命名 cassandra 集群名称 1.2.6 时出错

    我在具有单个节点的集群中使用 cassandra 1 2 6 我正在尝试使用以下说明重命名集群 Cassandra 集群名称不匹配 完成所有步骤后 当我更改 cassandra yaml 文件后启动 cassandra 时 我继续出现相同的
  • matplotlib 再次显示图形

    使用 matplotlib 时 from matplotlib import pyplot as plt figure plt figure ax figure add subplot 111 ax plot x y figure show
  • 废弃的命名信号量未释放

    当 C 程序持有命名信号量时 当应用程序提前终止 例如按 Ctrl C 或关闭控制台窗口 时 它似乎不会被释放 至少在该进程的所有实例都终止之前不会 对于命名互斥体 在这种情况下会引发 AbandonedMutexException 但对于