【问题标题】:How do I wait until a console application is idle?如何等到控制台应用程序空闲?
【发布时间】:2011-02-13 23:10:02
【问题描述】:

我有一个控制台应用程序启动,托管一堆服务(长时间运行的启动),然后等待客户端调用它。我有启动此控制台应用程序并进行“客户端”调用的集成测试。如何在调用客户端之前等待控制台应用程序完成启动?

我想避免使用Thread.Sleep(int),因为这取决于启动时间(可能会发生变化),如果启动速度更快,我会浪费时间。

Process.WaitForInputIdle 仅适用于具有 UI 的应用程序(我确认在这种情况下它确实会引发异常)。

我对尴尬的解决方案持开放态度,例如,让控制台应用程序在准备好时写入一个临时文件。

【问题讨论】:

  • 控制台应用程序托管 WCF 服务。 “客户端”进行 WCF 调用。如果控制台应用程序没有完成启动,客户端会收到 Endpoint Not Found 异常。

标签: c# timeout console-application


【解决方案1】:

一种选择是创建一个命名的 EventWaitHandle。这将创建一个您可以跨进程使用的同步对象。然后你让你的“客户端”应用程序等到事件发出信号后再继续。一旦主控制台应用程序完成启动,它就可以发出事件信号。

http://msdn.microsoft.com/en-us/library/41acw8ct(VS.80).aspx

例如,您的“服务器”控制台应用程序可能具有以下内容。这不是编译的,所以它只是一个起点:)

using System.Threading;
static EventWaitHandle _startedEvent;
static void main()
{  
  _startedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, @"Global\ConServerStarted");

  DoLongRunnningInitialization();

  // Signal the event so that all the waiting clients can proceed
  _startedEvent.Set();
}

然后客户会做这样的事情

using System.Threading;
static void main()
{  
  EventWaitHandle startedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, @"Global\ConServerStarted");

  // Wait for the event to be signaled, if it is already signalled then this will fall throught immediately.
  startedEvent.WaitOne();    

//  ... continue communicating with the server console app now ...
}

【讨论】:

  • 这个名字“做什么”?我使用了名称“MyCompany\HostStarted”,控制台应用程序抛出了 DirectoryNotFound 异常!
  • 我实际上应该提到这一点。 Global\ 或 Local\ 前缀控制事件的范围。 Global\ 使事件在所有会话中“可见”,而 Local\ 将使其仅在当前会话中可见。当应用程序在终端服务器会话上运行时,这是一个重要的区别,例如,根据您的要求,您可能希望在其中使用 Local\。
  • 这太棒了,有点可怕。我喜欢它。
  • 这太棒了!谢谢。我正在考虑做一个完整的管道实现,只是为了向我的应用程序发送一个“服务器”准备好的信号
【解决方案2】:

如何设置互斥锁,并在启动完成后将其删除。让客户端应用程序等到它可以获取互斥体后再开始执行操作。

【讨论】:

  • 原则上与我提供的答案类似,但是使用 EventWaitHandle 将允许多个客户端应用程序在主应用程序上同步。
【解决方案3】:

在应用程序的客户端界面中包含准备就绪检查,或者如果在准备好之前调用它,则返回未准备好错误。

【讨论】:

  • 所以应用程序需要检查循环,直到它不返回“我还没准备好错误”?不确定这是否是一个好方法...
【解决方案4】:

创建可用于查询服务器进程状态的 WCF 服务。仅当在命令行上传递特定命令时才启动此服务。以下特征将确保此服务的快速启动:

  • 将此服务作为客户端应用程序的第一个操作托管
  • 使用 net.tcp 或 net.pipe 绑定,因为它们非常快速启动
  • 使此服务尽可能简单,以确保只要控制台应用程序不终止,它就会保持可用

测试运行程序可以尝试连接到此服务。如果在控制台应用程序终止或相当短的超时期限到期之前失败,请重试尝试。只要控制台应用程序没有意外终止,您就可以依靠此服务在相当短的时间内开始测试之前提供任何其他信息。

【讨论】:

  • 工作量太大了,我们将这个东西作为生产服务托管,从来没有这种赛车问题。
【解决方案5】:
    1234563 、外部文件、注册表等)。
  • 另一种可能性是您得出控制台加载服务并在您的测试应用程序中使用该时间的平均时间;好吧,只是大声思考!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    • 2013-02-11
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多