Моно-приложение, использующее Console.CancelKeyPress, не может быть запущено в фоновом режиме - PullRequest
4 голосов
/ 22 февраля 2012

У меня есть консольное приложение в Mono под Linux, которое использует 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.

Если я попытаюсь отправить SIGINT, используя kill (что должно завершить процесс, поскольку обработчик не устанавливает 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, даже если вы отправите SIGINT, используя kill. UnixSignal то есть.

...