- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个在它自己的线程中运行的进程,可以在不阻塞的情况下启动/停止。这最终将进入 Windows 服务,但我现在在控制台应用程序中进行设置,直到它完全充实。
调用 Start() 后,我希望主程序线程阻塞,直到按下 Ctrl-C。我知道这会起作用:
public static void Main(string[] args)
{
bool keepGoing = true;
var service = new Service();
System.Console.TreatControlCAsInput = false;
System.Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
{
e.Cancel = true;
service.Stop();
keepGoing = false; // Break the while loop below
};
service.Start();
while( keepGoing )
{
Thread.Sleep(100); // 100 is arbitrary
}
}
但是,我发现标志和任意 sleep 值很麻烦。我知道 CPU 成本在 while 循环中几乎为 0,但我宁愿有一个“硬” block ,它会在 Ctrl-C 处理程序完成后立即释放。我设计了以下内容,使用信号量进行阻塞,直到匿名 Ctrl-C 处理程序完成:
public static void Main(string[] args)
{
var service = new Service();
var s = new Semaphore(1, 1);
System.Console.TreatControlCAsInput = false;
System.Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
{
e.Cancel = true;
service.Stop();
s.Release(); // This will allow the program to conclude below
};
service.Start();
s.WaitOne(); // This will not block
s.WaitOne(); // This will block w/o CPU usage until the sempahore is released
}
这是一个糟糕的设计吗?是不是矫枉过正?危险吗?
编辑:
我还连接 AppDomain.CurrentDomain.UnhandledException 如下:
AppDomain.CurrentDomain.UnhandledException += delegate {
service.Stop();
s.Release();
};
编辑第二个:
我应该指出,Stop()
方法在退出时被调用是至关重要的。 @Adam Ralph 有一个完美的混合控制台/服务模式,但在回答问题时没有此信息。
最佳答案
我们的一些应用程序也有类似的要求。它们是 Windows 服务,但为了调试,我们通常希望将它们作为控制台应用程序运行。此外,我们通常很早就将新应用程序编码为 Windows 服务,但通常不想等到后来(一旦我们证明了概念等)才将它们作为服务实际运行。
这是我们使用的模式:-
using (var service = new Service())
{
if (Environment.UserInterActive)
{
service.Start();
Thread.Sleep(Timeout.Infinite);
}
else
{
ServiceBase.Run(service);
}
}
让线程无限休眠看似效率低下,但这仅适用于调试场景,冗余线程不消耗 CPU 时间,只是一些内存(大约 1MB),主要由分配给线程的堆栈空间组成。该进程仍然可以使用 Ctrl+C 或关闭命令窗口退出。
-- 编辑--
如果您发现在按下 Ctrl+C 时未调用 service.Dispose()
(即发生了粗鲁的中止)并且调用了 Dispose()
是至关重要的,那么我想你可以明确地这样做:-
using (var service = new Service())
{
if (Environment.UserInterActive)
{
Console.CancelKeyPress += (sender, e) => service.Dispose();
service.Start();
Thread.Sleep(Timeout.Infinite);
}
else
{
ServiceBase.Run(service);
}
}
注意Stop()
应该封装在Dispose()
中。
关于c# - 使用信号量而不是 while 循环。这是好事还是坏事?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8347008/
我最近一直在阅读有关 SPA 以及它有多好的内容。 我想知道是否有人可以告诉我什么时候应该使用,或者什么时候不应该像常规 MVC 一样使用 SPA 最佳答案 MVC(Rails、MVC4)的工具更加成
当涉及到标签上的非标准属性时,HTML(或者可能只是 XHTML?)相对严格。如果它们不是规范的一部分,那么您的代码将被视为不合规。 但是,非标准属性对于将元数据传递给 Javascript 可能非常
我正在定义我的 DbConntextObj _container.RegisterType(new HttpContextLifetimeManager()); Unity 没有在 lifetimem
我们看到大量虚拟内存碎片和内存不足错误,然后达到了 3GB 限制。 编译调试在 web.config 中设置为 true,但我从每个人那里得到了不同的答案,调试设置为 true 是否会导致每个 asp
我是一名优秀的程序员,十分优秀!