17 Stimmen

Wie bringe ich diese ereignisbasierte Konsolenanwendung dazu, sich nicht sofort zu beenden?

Quelle

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);
    }
}

Frage

Das sollte ziemlich selbsterklärend sein. Ich versuche, einen Datei-Überwacher zu erstellen, damit ich meine Videos automatisch sortieren kann... wie schaffe ich es, dass sich das Programm nie beendet?

Ich möchte es zunächst konsolenbasiert halten, damit ich es debuggen kann, aber irgendwann möchte ich die Konsole entfernen und es einfach im Hintergrund laufen lassen (ich schätze als Dienst).

22voto

M.Babcock Punkte 18351

Vielleicht etwa so:

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);
    }
}

アップデート

Um allen anderen zu helfen, die nach einer ähnlichen Lösung suchen, gibt es, wie @Mark in den Kommentaren schrieb, auch eine Möglichkeit, die WaitForChanged Methode der FileSystemWatcher Klasse, um diese Frage zu lösen:

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

Auf diese Weise kann die Anwendung unendlich lange (oder bis zum Abbruch des while) auf die Änderung einer Datei warten.

7voto

mpen Punkte 253762
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);
    }

}

Ich musste einfach EnableRaisingEvents offenbar.


Ich habe eine andere Lösung gefunden, die vielleicht noch schöner ist:

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);
    }
}

2voto

Ry- Punkte 208020

Damit können Sie ewig warten:

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

2voto

Scott Chamberlain Punkte 120610

Ich hatte genau das gleiche Problem wie Sie. Was ich getan habe, ist, wenn das Programm mit der Befehlszeile gestartet wird --console werden Sie aufgefordert, die Eingabetaste zu drücken, um das Programm zu schließen. Wenn keine Parameter angegeben sind, wird erwartet, dass es als Dienst gestartet wird.

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
}

2voto

Tomislav Markovski Punkte 12031

Konsolenanwendungen sind aufgrund dieses Szenarios nie eine gute Möglichkeit, Ereignisse zu testen. Unabhängig von der Methode, die Sie verwenden, muss der aktuelle Thread angehalten werden, entweder im Ruhezustand oder in einer while(true)-Schleife, was das Auslösen von Ereignissen verhindert oder es fast unmöglich macht, Haltepunkte innerhalb von Ereignissen zu erreichen. Verwenden Sie eine Windows-Anwendung, wenn Sie können.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X