使用 Console.CancelKeyPress 的 Mono 应用程序无法在后台运行

发布于 2025-01-08 17:44:02 字数 1578 浏览 0 评论 0原文

我在 Linux 下的 Mono 中有一个控制台应用程序,它使用 Console.CancelKeyPress 来侦听 SIGINT。但是,该应用程序拒绝在后台运行,因为它总是立即停止。

这是一个简化的示例:

using System;
using System.Threading;

static class Program
{
    static void Main()
    {
        Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
        Console.WriteLine("Sleeping");
        Thread.Sleep(100000);
        Console.WriteLine("Done");
    }

    static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
    {
        Console.WriteLine("In handler.");
    }
}

如果我尝试在 bash 下在后台运行此应用程序,结果如下:

~/test$ mono test.exe &
[1] 4516
~/test$

[1]+  Stopped                 mono test.exe
~/test$

我必须再次按 Enter 才能看到“已停止”消息,但它立即发生。正如您所看到的,它永远不会到达 Console.WriteLine 调用。

如果我尝试使用 kill 发送 SIGINT (这应该结束该进程,因为处理程序未将 e.Cancel 设置为 true),直到我使用 fg 恢复进程,此时它立即结束(它永远不会进入处理程序)。

如果我在前台启动该进程,然后使用 ctrl-z 中断它并使用 bg,它会再次立即停止,只有这一次我发送 SIGINT 然后使用 fg 恢复它,处理程序确实被调用。

如果我删除Console.CancelKeyPress事件处理程序分配,该进程在后台运行得很好。

我正在使用 Mono 2.10.8 和 Debian 6.0.2。

如果一切都失败了,我可以使用 Mono.Unix.UnixSignal 复制我需要的功能,但如果有人对此有解决方案,我绝对想听听。

更新:对于我的目的来说,Console.CancelKeyPress似乎还有另一个问题。我将使用 nohup 运行我的进程,因此输入不是控制台而是 /dev/null。在这种情况下,Mono 永远不会触发 CancelKeyPress 事件,即使您使用 kill 发送 SIGINT。那么,UnixSignal 就是这样。

I have a console application in Mono under Linux that uses Console.CancelKeyPress to listen for SIGINT. However, this applications refuses to run in the background, as it always immediately gets stopped.

Here's a reduced example:

using System;
using System.Threading;

static class Program
{
    static void Main()
    {
        Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
        Console.WriteLine("Sleeping");
        Thread.Sleep(100000);
        Console.WriteLine("Done");
    }

    static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
    {
        Console.WriteLine("In handler.");
    }
}

If I try to run this application in the background under bash, this is the result:

~/test$ mono test.exe &
[1] 4516
~/test$

[1]+  Stopped                 mono test.exe
~/test$

I had to hit enter again to see the "stopped" message, but it happens immediately. As you can see, it never reaches the Console.WriteLine call.

If I try to send SIGINT using kill (which should end the process because the handler doesn't set e.Cancel to true), nothing happens until I resume the process using fg, at which point it ends immediately (it never enters the handler).

If I start the process in the foreground, then interrupt it with ctrl-z and use bg, it again gets stopped immediately, only this time if I send SIGINT and then resume it with fg, the handler does get invoked.

If I remove the Console.CancelKeyPress event handler assignment, the process runs in the background just fine.

I'm using Mono 2.10.8 and Debian 6.0.2.

If all else fails, I can replicate the functionality I need using Mono.Unix.UnixSignal, but if someone has a solution for this I'd definitely like to hear it.

UPDATE: It seems there's another problem with Console.CancelKeyPress for my purposes. I will run my process using nohup so the input is not a console but /dev/null. In this situation, Mono will never trigger the CancelKeyPress event, even if you send SIGINT using kill. UnixSignal it is, then.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文