我有一个IIS ASP.Net Web服务,它将启动一个.net控制台应用程序。我想为控制台应用程序提供优雅的关闭。 (即)关闭请求将来自Web服务,控制台应用程序将响应&优雅地关机。是否可以在不使用任何端口的情况下执行此操作?
我能想到的一个解决方案是建立从控制台应用程序到Web服务的长轮询链接。控制台应用程序是否可以在不使用端口的情况下建立侦听机制?我的部署环境有一些安全扫描程序正在运行,如果它找到未经批准的开放端口,那就很糟糕了。
答案 0 :(得分:3)
我打算说你可以使用一个名为Mutex,但是考虑到ASP.Net的多线程野兽,你不能保证拥有的线程与发布它的线程相同。这可能会导致问题。 SO ...
最简单的方法可能是使用文件系统。
让控制台应用程序实例化FileSystemWatcher以监视两个进程可以访问更改的目录,并为Created event连接一个事件处理程序,如下所示:
internal static bool ShutDownRequested { get ; set ; }
private static void OnCreated( object sender , FileSystemEventArgs fileSystemEventArgs )
{
FileSystemWatcher watcher = (FileSystemWatcher) sender ;
ShutDownRequested = true ;
File.Delete( fileSystemEventArgs.FullPath ) ;
watcher.Created -= OnCreated ;
}
static void Main()
{
using ( FileSystemWatcher watcher = new FileSystemWatcher( @"\some\common\directory" , "foobar.shutdown.requested" ) )
{
watcher.Created += OnCreated;
while ( !ShutDownRequested )
{
DoSomethingUseful() ;
}
}
return ;
}
如果要关闭控制台应用程序,只需创建控制台应用程序所期望的文件即可。控制台应用程序的事件处理程序捕获工作线程上的事件,然后可以设置全局关闭标志,以便主线程可以在第一个适当时间正常关闭,或者事件处理程序可以简单地调用Environment.Exit(int)
并强制关闭它。不要忘记通过在完成工作后删除sentinel文件来整理一些东西(这是唯一有礼貌的事情)。
这就是我要做的事情,但是,我对过度思考的事情并不陌生。
在过度思考中,您可以以类似的方式使用命名事件。在ASP.Net服务中,创建了一个最初未取消标记的命名事件:
// start console app
EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.ManualReset,"foobar.shutdown.signal");
SpawnConsoleApp() ;
然后,当关闭控制台应用程序的时候:
// shutdown time
wh.Set() ;
(别忘了将等待处存放在一些安全的地方)
在您的控制台应用中,您需要定期检查信号:
static void Main()
{
EventWaitHandle wh = EventWaitHandle.OpenExisting( "foobar.shutdown.signal" ) ;
while( !wh.WaitOne(0) )
{
DoSomethingUseful() ;
}
wh.Set() ; // acknowledge the signal
return ;
}
答案 1 :(得分:3)
http://msdn.microsoft.com/en-us/library/bb762927(v=vs.110).aspx
.NET Framework内置了对命名管道的支持,这是一种不使用端口的IPC。
使用管道非常常见。 Microsoft IIS Admin Service使用管道与工作进程通信,这是一个示例。
答案 2 :(得分:1)
我不是WCF专家,但this answer看起来会有所帮助。他在choosing a transport上引用了这篇MSDN文章。
从那篇文章:
何时使用命名管道传输
... 当在一台计算机上的不同WCF应用程序之间需要通信,并且您想要阻止来自另一台计算机的任何通信时,请使用命名管道传输...