C# 如何使此基于事件的控制台应用程序不立即终止? 来源 问题:

C# 如何使此基于事件的控制台应用程序不立即终止? 来源 问题:,c#,events,filesystemwatcher,C#,Events,Filesystemwatcher,应该是不言自明的。我正在尝试创建一个文件查看器,这样我就可以自动对我的视频进行排序…我如何使程序永远不会终止 现在我想让它基于控制台,以便调试它,但最终我想删除控制台,让它在后台运行(我想是作为一项服务)。您可以使用以下方法永远等待: System.Threading.Thread.Sleep(-1); 也许是这样的: class Program { static void Main(string[] args) { var fw = new FileSyste

应该是不言自明的。我正在尝试创建一个文件查看器,这样我就可以自动对我的视频进行排序…我如何使程序永远不会终止


现在我想让它基于控制台,以便调试它,但最终我想删除控制台,让它在后台运行(我想是作为一项服务)。

您可以使用以下方法永远等待:

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

也许是这样的:

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在评论中所述,本着帮助其他可能正在寻找类似解决方案的人的精神,还有一种方法可以使用
FileSystemWatcher
类的
WaitForChanged
方法来解决此问题:

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

这样做允许应用程序无限期地等待(或直到while被破坏)文件被更改。

我遇到了与您完全相同的问题。我所做的是,如果使用命令行
--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
}

由于这种情况,控制台应用程序永远不是测试事件的好方法。无论您使用什么方法,它都必须停止当前线程,或者在某个while(true)循环中休眠或锁定,这会阻止事件触发,或者使事件中的断点几乎不可能命中。 如果可以,请使用windows应用程序

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

}
显然,我必须
启用raisingevents


找到了另一个可能更好的解决方案:

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


您希望什么事件导致您的应用程序停止?@M.Babcock:我不希望停止它。我将在windows上使用Ctrl+Alt+Del强制关闭它。或者在我开发时,通过X关闭控制台窗口可以终止它。最终它将通过停止windows服务而终止。描述为“获取指定对象上的独占锁”。。。不知道这有什么用,但我还是试过了。什么都不做;仍然立即关闭。用
obj
fw
试过@Mark:完全正确!无论如何,我已经用更好的解决方案更新了我的答案。不……这将等待键盘输入,不允许任何事件通过。@Mark:No,
FileSystemWatcher
是异步的。您需要将
EnableRaisingEvents
属性设置为
true
-刚刚注意到:)另外,我的答案中有一个更优雅的解决方案。您是对的。我知道它是异步的,但我认为这意味着它不会停止执行,但我认为
ReadLine
实际上会占用所有线程,不会让任何内容通过…但我猜它只占用一个线程,异步事件将在一个单独的线程上触发…这将保持窗口打开…但我认为这会阻止文件监视程序接收事件,除非我编程错误…“添加的文件”在所述目录中创建文件时不会被命中。呃…我应该改为使用“创建的”事件,但这是同样的问题。设置事件处理程序后,需要将EnableRaisingEvents设置为true。我已经更新了答案,以说明如何更新。查看FileSystemWatcher文档中的示例了解更多信息:Ooo…它还有一个
WaitForChanged
函数。这样我们就不必使用单独的线程对象。我喜欢AutoResetEvent方法,因为我有多个触发事件的FSW对象,所以WaitForChanged方法对我不起作用。呃……也许我遗漏了什么,但只是添加了
Console.ReadLine()似乎也不起作用。我认为它在等待输入而不接受事件,不是吗?
ServiceBase
是您的类之一,还是我也应该继承的类?要完成Mark要求的最小任务,代码似乎太多了。ServiceBase是。当我编写服务时,我希望我的调试尽可能接近正在运行的服务。事件将在等待ReadLine()时归档,但我认为您的问题是,您需要将EnableRaisingEvents设置为true。“除非您将EnableRaisingEvents设置为true,否则组件不会引发事件”@ScottChamberlain:您是对的!我没想过要寻找这样一个选项。如果你不想监听事件,为什么要创建一个文件系统监视程序@标记您可能希望延迟观看,直到您准备好接收事件或其他事情发生。设置后,禁用和启用比启用和忽略消息更容易,直到您有机会停止。似乎是目前为止唯一合法的解决方案。我可以这样做,但控制台应用程序似乎更方便,因为我只将其用作调试窗口。但这样做通常是为了使windows服务更容易使用。对于其他事件也很好。使用计时器尝试,不会阻止执行。
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);
    }
}