Pergunta

I have an IIS ASP.Net web service that will kick off a .net console application. I want to provide a graceful shut down for the console app. (ie) The shut down request will originate from web service and the console app will respond & gracefully shutdown. Is it possible to do this without using any port ?

One solution I can think of is to establish a long poll link from console app to web service. Is there any other way where the console app can establish a listening mechanism without using ports ? My deployment environment has some security scanners running, if it finds an unapproved open port, it is bad.

Foi útil?

Solução 3

I'm not a WCF expert, but this answer looks like it would help. He refers to this MSDN article on choosing a transport.

From that article:

When to Use the Named Pipe Transport

... When communication is required between different WCF applications on a single computer, and you want to prevent any communication from another machine, then use the named pipes transport...

Outras dicas

I was going to say that you could use a named Mutex, but given the multi-threaded beast that is ASP.Net, you wouldn't be guaranteed that the owning thread would be the same thread that releases it. That would likely cause problems. SO...

The easiest method would probably be to use the file system.

Have the console app instantiate a FileSystemWatcher to monitor a directory that both processes can access for changes and wire up an event handler for the Created event, something like this:

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

When you want to shut down the console app, just create the file the console app is expecting. The console app's event handler catches the event on a worker thread and can then set the global shutdown flag so the main thread can gracefully shutdown at the first opportune time, or the event handler can simply invoke Environment.Exit(int) and force it down. Don't forget to tidy things up by deleting the sentinel file after it's done its job (it's the only polite thing to do).

That's what I'd do, but then, I'm not big on over-thinking things.

On overthinking, you can use a named event in a similar fashion. In your ASP.Net service, created a named event that's initially unsignalled:

// start console app
EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.ManualReset,"foobar.shutdown.signal");
SpawnConsoleApp() ;

Then, when it's time to shut down the console app:

// shutdown time
wh.Set() ;

(Don't forget to stow the wait handle some place safe)

In your console app, you need to periodically check for a signal:

static void Main()
{
  EventWaitHandle wh = EventWaitHandle.OpenExisting( "foobar.shutdown.signal" ) ;
  while( !wh.WaitOne(0) )
  {
    DoSomethingUseful() ;
  }
  wh.Set() ; // acknowledge the signal
  return ;
}

http://msdn.microsoft.com/en-us/library/bb762927(v=vs.110).aspx

.NET Framework has built-in support for named pipes, which is an IPC without using ports.

It is very common to use pipes. Microsoft IIS Admin Service uses pipes to communicate with worker process, which is an example.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top