L
Lothar Behrens
Hi,
I have created a plugin system that put each plugin into a separate
domain (monitoring stuff). A test with the following code shows up
that I catch the exception from a thread in the second domain, but
after the handler the application still keeps stopping.
I even can stop and restart the services, but after that the
application reports about the exception.
Why?
Thanks, Lothar
public bool startupServives(string pluginManagerModule, string
pluginManagerClass)
{
// Service 0
AppDomain appDomainPlugin =
AppDomain.CreateDomain("PluginDomain-" + plm.PluginModule + "-" +
plm.PluginClass);
appDomainPlugin.UnhandledException +=
OnUnhandledException;
IMonitoringPlugin monitoringPlugin =
(IMonitoringPlugin)appDomainPlugin.CreateInstanceAndUnwrap(
"MyPlugin",
"MyPluginNS.Plugin1",
true, // ignoreCase
0, // bindingAttr
null, // binder
null, // args
null, // culture
null, // activationAttributes
null // securityAttributes
);
monitoringPlugin.Initialize();
runningServices.Add(monitoringPlugin);
runningDomains.Add(appDomainPlugin);
// Service 1
// ...
monitoringPlugin1.Initialize();
runningServices.Add(monitoringPlugin1);
runningDomains.Add(appDomainPlugin1);
}
public bool shutdownServices()
{
if (runningServices == null) return true;
if (runningDomains == null) return true;
foreach (IMonitoringPlugin pl in runningServices)
{
pl.Dispose();
}
runningServices = null;
foreach (AppDomain ap in runningDomains)
{
AppDomain.Unload(ap);
}
runningDomains = null;
GC.Collect();
return true;
}
// Handler gets called upon timed out thread in second domain
void OnUnhandledException(object sender,
UnhandledExceptionEventArgs eventArgs)
{
shutdownServices();
startupServives(_pluginManagerModule,
_pluginManagerClass);
}
The plugin that tests the exception in thread issue:
public class PluginExceptionSample : MarshalByRefObject,
IMonitoringPlugin, IDisposable
{
public string Name
{
get
{
return "PluginExceptionSample";
}
}
public string Description
{
get
{
return "Sample plugin exception sample";
}
}
public string Author
{
get
{
return "Lothar Behrens";
}
}
public string Version
{
get
{
return "1.0.0.0";
}
}
public void Initialize()
{
System.Console.WriteLine("Plugin " + Name + ", " + Version
+ ", " + Author + " initialized.");
System.Console.Beep();
ExceptionThread = new Thread(ExceptionAction);
ExceptionThread.Start();
}
public void Dispose()
{
System.Console.WriteLine("Plugin " + Name + ", " + Version
+ ", " + Author + " disposing.");
System.Console.Beep();
}
void ExceptionAction()
{
Thread.Sleep(5000);
throw new Exception("ExceptionAction() throwed and
exception.");
}
Thread ExceptionThread;
}
I have created a plugin system that put each plugin into a separate
domain (monitoring stuff). A test with the following code shows up
that I catch the exception from a thread in the second domain, but
after the handler the application still keeps stopping.
I even can stop and restart the services, but after that the
application reports about the exception.
Why?
Thanks, Lothar
public bool startupServives(string pluginManagerModule, string
pluginManagerClass)
{
// Service 0
AppDomain appDomainPlugin =
AppDomain.CreateDomain("PluginDomain-" + plm.PluginModule + "-" +
plm.PluginClass);
appDomainPlugin.UnhandledException +=
OnUnhandledException;
IMonitoringPlugin monitoringPlugin =
(IMonitoringPlugin)appDomainPlugin.CreateInstanceAndUnwrap(
"MyPlugin",
"MyPluginNS.Plugin1",
true, // ignoreCase
0, // bindingAttr
null, // binder
null, // args
null, // culture
null, // activationAttributes
null // securityAttributes
);
monitoringPlugin.Initialize();
runningServices.Add(monitoringPlugin);
runningDomains.Add(appDomainPlugin);
// Service 1
// ...
monitoringPlugin1.Initialize();
runningServices.Add(monitoringPlugin1);
runningDomains.Add(appDomainPlugin1);
}
public bool shutdownServices()
{
if (runningServices == null) return true;
if (runningDomains == null) return true;
foreach (IMonitoringPlugin pl in runningServices)
{
pl.Dispose();
}
runningServices = null;
foreach (AppDomain ap in runningDomains)
{
AppDomain.Unload(ap);
}
runningDomains = null;
GC.Collect();
return true;
}
// Handler gets called upon timed out thread in second domain
void OnUnhandledException(object sender,
UnhandledExceptionEventArgs eventArgs)
{
shutdownServices();
startupServives(_pluginManagerModule,
_pluginManagerClass);
}
The plugin that tests the exception in thread issue:
public class PluginExceptionSample : MarshalByRefObject,
IMonitoringPlugin, IDisposable
{
public string Name
{
get
{
return "PluginExceptionSample";
}
}
public string Description
{
get
{
return "Sample plugin exception sample";
}
}
public string Author
{
get
{
return "Lothar Behrens";
}
}
public string Version
{
get
{
return "1.0.0.0";
}
}
public void Initialize()
{
System.Console.WriteLine("Plugin " + Name + ", " + Version
+ ", " + Author + " initialized.");
System.Console.Beep();
ExceptionThread = new Thread(ExceptionAction);
ExceptionThread.Start();
}
public void Dispose()
{
System.Console.WriteLine("Plugin " + Name + ", " + Version
+ ", " + Author + " disposing.");
System.Console.Beep();
}
void ExceptionAction()
{
Thread.Sleep(5000);
throw new Exception("ExceptionAction() throwed and
exception.");
}
Thread ExceptionThread;
}