Как заставить это консольное приложение на основе событий не завершать работу немедленно? - PullRequest
17 голосов
/ 30 декабря 2011

Источник

class Program
{
    static void Main(string[] args)
    {
        var fw = new FileSystemWatcher(@"M:\Videos\Unsorted");
        fw.Created+= fw_Created;
    }

    static void fw_Created(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine("added file {0}", e.Name);
    }
}

Вопрос

Должен быть довольно понятным.Я пытаюсь создать средство просмотра файлов, чтобы я мог автоматически сортировать свои видео для себя ... как мне заставить программу не прерываться, когда-либо?

Сейчас я хочу, чтобы она поддерживала консоль, поэтомуЯ могу отладить его, но в конце концов я хочу удалить консоль и просто запустить ее в фоновом режиме (я думаю, в качестве службы).

Ответы [ 5 ]

22 голосов
/ 30 декабря 2011

Возможно что-то вроде этого:

class Program
{
    static void Main(string[] args)
    {
        var fw = new FileSystemWatcher(@"M:\Videos\Unsorted");
        fw.Changed += fw_Changed;
        fw.EnableRaisingEvents = true;

        new System.Threading.AutoResetEvent(false).WaitOne();
    }

    static void fw_Changed(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine("added file {0}", e.Name);
    }
}

Обновление

В духе помощи кому-либо, кто может искать подобное решение, как @Mark заявил в комментариях, есть также способ использовать метод WaitForChanged класса FileSystemWatcher для решения этого вопроса:

class Program
{
    static void Main(string[] args)
    {
        var fw = new FileSystemWatcher(@".");
        while (true)
        {
            Console.WriteLine("added file {0}",
                fw.WaitForChanged(WatcherChangeTypes.All).Name);
        }
    }
}

Это позволяет приложению ожидать в течение неопределенного времени (или до тех пор, пока не прервется время) изменения файла.

7 голосов
/ 30 декабря 2011
class Program
{
    static void Main(string[] args)
    {
        var fw = new FileSystemWatcher(@"M:\Videos\Unsorted");
        fw.EnableRaisingEvents = true;
        fw.Created += fw_Created;

        Console.ReadLine();

    }

    static void fw_Created(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine("added file {0}", e.Name);
    }

}

Просто надо было EnableRaisingEvents, видимо.


Нашли другое решение, которое, возможно, даже лучше:

class Program
{
    static void Main(string[] args)
    {
        var fw = new FileSystemWatcher(@"M:\Videos\Unsorted");
        fw.Created += fw_Created;
        while(true) fw.WaitForChanged(WatcherChangeTypes.All);
    }

    static void fw_Created(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine("added file {0}", e.Name);
    }
}
2 голосов
/ 30 декабря 2011

Консольные приложения никогда не являются хорошим способом тестирования событий из-за этого сценария. Какой бы метод вы ни использовали, он должен останавливать текущий поток, либо находиться в спящем режиме, либо блокировать в некотором цикле while (true), что предотвращает запуск ваших событий или делает почти невозможным попадание в точки останова внутри событий. Используйте приложение для Windows, если можете.

2 голосов
/ 30 декабря 2011

У меня была точно такая же проблема, как и у вас.Что я сделал, если программа запущена с командной строкой --console, она предложит вам нажать Enter, чтобы закрыть, если нет параметров, которые она будет ожидать как служба.

class MyExampleApp : ServiceBase
{

    public static void Main(string[] args)
    {
        if (args.Length == 1 && args[0].Equals("--console"))
        {
            new MyExampleApp().ConsoleRun();
        }
        else
        {
            ServiceBase.Run(new MyExampleApp());
        }
    }
    private void ConsoleRun()
    {
        Console.WriteLine(string.Format("{0}::starting...", GetType().FullName));

        OnStart(null);

        Console.WriteLine(string.Format("{0}::ready (ENTER to exit)", GetType().FullName));
        Console.ReadLine();

        OnStop();

        Console.WriteLine(string.Format("{0}::stopped", GetType().FullName));
    }
    //snip
}
2 голосов
/ 30 декабря 2011

Вы можете ждать вечно, используя это:

System.Threading.Thread.Sleep(-1);
...