首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将输入馈送到Console.ReadKey

将输入馈送到Console.ReadKey
EN

Stack Overflow用户
提问于 2010-09-18 04:18:44
回答 3查看 2.3K关注 0票数 0

我有一个调用Filewatcher函数的程序,如下所示

代码语言:javascript
复制
Main()  
{  
    watch();        
    console.Readkey();
}

我在末尾有console.readkey,因为我不想让控制台在监视文件更改时显示'Press any key to continue‘。现在,如果检测到更改,则触发另一个函数,该函数执行其工作,并最终再次调用main,该函数再次停止于console.readkey。

在这一点上,我遇到了一些奇怪的问题,比如程序需要两个键输入才能继续。我猜这是因为前面的console.readkey还在等待输入,所以第一个输入在那里,然后第二个输入到第二个console.readkey。

所以,我的问题是,当文件守护程序第一次被触发时,我是否可以通过代码向console.readkey提供一些东西,即等待用户输入?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-09-18 04:23:23

Console.ReadKey将阻止该程序,直到您按下某个键(此时它将读取该按键并返回)。

听起来,在这种情况下,您需要将逻辑更改为无限循环(或直到达到其他条件)。您应该考虑重写应用程序,而不是使用Console.ReadKey来阻止应用程序结束:

代码语言:javascript
复制
bool exitProgram = false;
AutoResetEvent resetEvent = new AutoResetEvent();

void Main()
{
    while (!exitProgram)
    {
        Watch(); // Starts FileSystemWatcher
        resetEvent.WaitOne();
    }
}

void WorkFinished() // Call at the end of FileSystemWatcher's event handler
{
     resetEvent.Set(); // This "reschedules" the watcher...
}

这将使程序“永远”运行,直到您将exitProgram设置为true,此时它将正常退出。“监视”将不会被连续调用,因为resetEvent将无限期地阻塞。当“工作”完成时(在FileSystemWatcher事件处理程序完成之后),调用resetEvent.Set()。这将导致循环再次重复,重新触发您的手表代码。

它的工作原理是使用一个AutoResetEvent来防止观察者重复地“重新查看”同一个文件。

票数 1
EN

Stack Overflow用户

发布于 2010-09-18 04:34:53

您的控制台应用程序的结构应该更改为使用WaitHandle和Ctrl+C退出程序。这样一个程序的基本结构如下所示。转换成C#应该是微不足道的。

代码语言:javascript
复制
Module modMain

    Public shutdown As New Threading.ManualResetEvent(False)

    Public Sub FileCreated(ByVal sender As Object, ByVal e As IO.FileSystemEventArgs)
        Console.WriteLine("Created: " & e.FullPath)
    End Sub

    Public Sub FileChanged(ByVal sender As Object, ByVal e As IO.FileSystemEventArgs)
        Console.WriteLine("Changed: " & e.FullPath)
    End Sub

    Public Sub FileDeleted(ByVal sender As Object, ByVal e As IO.FileSystemEventArgs)
        Console.WriteLine("Deleted: " & e.FullPath)
    End Sub

    Public Sub FileRenamed(ByVal sender As Object, ByVal e As IO.FileSystemEventArgs)
        Console.WriteLine("Renamed: " & e.FullPath)
    End Sub

    Public Sub CancelKeyHandler(ByVal sender As Object, ByVal e As ConsoleCancelEventArgs)
        e.Cancel = True
        shutdown.Set()
    End Sub

    Sub Main()

        Dim fsw As New System.IO.FileSystemWatcher

        Try

            AddHandler Console.CancelKeyPress, AddressOf CancelKeyHandler

            ' Do your work here 
            ' press Ctrl+C to exit 
            fsw = New System.IO.FileSystemWatcher("c:\path")
            fsw.Filter = "*.*"
            fsw.NotifyFilter = (IO.NotifyFilters.Attributes Or IO.NotifyFilters.CreationTime Or IO.NotifyFilters.DirectoryName Or _
                                IO.NotifyFilters.FileName Or IO.NotifyFilters.LastAccess Or IO.NotifyFilters.LastWrite Or _
                                IO.NotifyFilters.Security Or IO.NotifyFilters.Size)
            AddHandler fsw.Created, AddressOf FileCreated
            AddHandler fsw.Changed, AddressOf FileChanged
            AddHandler fsw.Deleted, AddressOf FileDeleted
            AddHandler fsw.Renamed, AddressOf FileRenamed
            fsw.EnableRaisingEvents = True

            shutdown.WaitOne()

        Catch ex As Exception
            Console.WriteLine(ex.ToString())
        Finally
            If fsw IsNot Nothing Then fsw.Dispose()
        End Try

    End Sub

End Module
票数 1
EN

Stack Overflow用户

发布于 2010-09-18 04:21:55

this question和这里阅读,我认为你需要重构你的代码,并从WinForms处借用一个消息循环来保持你的程序存活。

添加对System.Windows.Forms.dll的引用。在main方法中,启动您的观察器。然后调用Application.Run()不用担心,你的应用程序仍然可以使用控制台,等等,Run()只会启动一个消息循环,并阻止你的程序继续到main方法的结尾。

然后重构上一个问题中的代码,这样它就不会再次调用Main()

无论何时想要停止应用程序,都可以调用Application.Exit()

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3738731

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档