N
nickdu
I seem to have an intermittant problem shutting down an appdomain. I say
this because sometimes my application is still running when it thinks it has
shutdown. Here is my scenario:
I've written a .NET service. I pass an argument to this service specifying
the service name. My Service.OnStart() creates an application domain so that
I can set the application configuration file to the '<service name>.config'.
It then creates a server object in this appdomain. This server object
provides the functionality of the application. This server object exposes a
Stopped event so that the service can get notified when the server has
stopped so that it can stop the service.
This seems to work many times. However, there are times when I see the
event in the event log that the server has stopped yet the service is still
running. Am I doing something wrong in shutting down the appdomain and/or
service?
Below is a snippet of the code:
..
..
..
[Serializable]
public class ServerFactory : MarshalByRefObject
{
public ServerFactory()
{
}
public Server Create()
{
// Create from configuration.
return (Server) ConfigurationManager.GetSection("eventProcessor");
}
}
public class Service : ServiceBase
{
private AppDomain _domain;
private Server _server;
private delegate void Control();
private void OnStopped(object sender, EventArgs args)
{
Control control = this.Stop;
control.BeginInvoke(null, null);
// Stop();
}
protected override void OnStart(string[] args)
{
try
{
args = Environment.GetCommandLineArgs();
if (args.Length != 2)
throw(new InvalidOperationException("Missing service name
argument."));
// Create AppDomain.
AppDomainSetup setup = new AppDomainSetup();
setup.ConfigurationFile = args[1] + ".config";
this._domain = AppDomain.CreateDomain("Service",
AppDomain.CurrentDomain.Evidence,
setup);
// Create factory in domain and have it create the server.
ServerFactory factory = (ServerFactory)
this._domain.CreateInstanceAndUnwrap(
Assembly.GetExecutingAssembly().FullName,
typeof(ServerFactory).FullName);
this._server = factory.Create();
/*
// Create from configuration.
this._server = (Server)
ConfigurationManager.GetSection("eventProcessor");
*/
// Fail if no configuration found.
if (this._server == null)
throw(new InvalidOperationException("Missing EventProcessor
configuration."));
this._server.Stopped += OnStopped;
this._server.Start(args[1]);
}
catch(Exception e)
{
try
{
EventLog.WriteEntry((args.Length != 2) ?
Server.EventSourceName : args[1],
string.Format("Failed starting EventProcessor: {0}",
e.ToString()),
EventLogEntryType.Error);
}
catch(Exception)
{
}
if (this._server != null)
{
this._server.Stopped -= OnStopped;
this._server = null;
}
AppDomain.Unload(this._domain);
throw;
}
}
protected override void OnStop()
{
if (this._server != null)
{
this._server.Stopped -= OnStopped;
this._server.Stop();
this._server = null;
}
AppDomain.Unload(this._domain);
}
public override object InitializeLifetimeService()
{
return null;
}
public static void Main()
{
ServiceBase.Run(new Service());
}
}
--
Thanks,
Nick
(e-mail address removed)
remove "nospam" change community. to msn.com
this because sometimes my application is still running when it thinks it has
shutdown. Here is my scenario:
I've written a .NET service. I pass an argument to this service specifying
the service name. My Service.OnStart() creates an application domain so that
I can set the application configuration file to the '<service name>.config'.
It then creates a server object in this appdomain. This server object
provides the functionality of the application. This server object exposes a
Stopped event so that the service can get notified when the server has
stopped so that it can stop the service.
This seems to work many times. However, there are times when I see the
event in the event log that the server has stopped yet the service is still
running. Am I doing something wrong in shutting down the appdomain and/or
service?
Below is a snippet of the code:
..
..
..
[Serializable]
public class ServerFactory : MarshalByRefObject
{
public ServerFactory()
{
}
public Server Create()
{
// Create from configuration.
return (Server) ConfigurationManager.GetSection("eventProcessor");
}
}
public class Service : ServiceBase
{
private AppDomain _domain;
private Server _server;
private delegate void Control();
private void OnStopped(object sender, EventArgs args)
{
Control control = this.Stop;
control.BeginInvoke(null, null);
// Stop();
}
protected override void OnStart(string[] args)
{
try
{
args = Environment.GetCommandLineArgs();
if (args.Length != 2)
throw(new InvalidOperationException("Missing service name
argument."));
// Create AppDomain.
AppDomainSetup setup = new AppDomainSetup();
setup.ConfigurationFile = args[1] + ".config";
this._domain = AppDomain.CreateDomain("Service",
AppDomain.CurrentDomain.Evidence,
setup);
// Create factory in domain and have it create the server.
ServerFactory factory = (ServerFactory)
this._domain.CreateInstanceAndUnwrap(
Assembly.GetExecutingAssembly().FullName,
typeof(ServerFactory).FullName);
this._server = factory.Create();
/*
// Create from configuration.
this._server = (Server)
ConfigurationManager.GetSection("eventProcessor");
*/
// Fail if no configuration found.
if (this._server == null)
throw(new InvalidOperationException("Missing EventProcessor
configuration."));
this._server.Stopped += OnStopped;
this._server.Start(args[1]);
}
catch(Exception e)
{
try
{
EventLog.WriteEntry((args.Length != 2) ?
Server.EventSourceName : args[1],
string.Format("Failed starting EventProcessor: {0}",
e.ToString()),
EventLogEntryType.Error);
}
catch(Exception)
{
}
if (this._server != null)
{
this._server.Stopped -= OnStopped;
this._server = null;
}
AppDomain.Unload(this._domain);
throw;
}
}
protected override void OnStop()
{
if (this._server != null)
{
this._server.Stopped -= OnStopped;
this._server.Stop();
this._server = null;
}
AppDomain.Unload(this._domain);
}
public override object InitializeLifetimeService()
{
return null;
}
public static void Main()
{
ServiceBase.Run(new Service());
}
}
--
Thanks,
Nick
(e-mail address removed)
remove "nospam" change community. to msn.com