我已经开发了能够运行一些插件的Windows服务。由于其性质,在开发Windows服务时,Start和Stop方法应运行并尽快返回。 Start
方法从所有插件运行Start
方法,这也不应阻止执行。在此示例中,两个插件都实例化了一个Threading.Timer,它在后台运行。
执行顺序如下。箭头指示在不同线程中运行的内容:
-> MyService.Start -> pA.Start -> pb.Start -> return
\_> DoWork() \
\_> DoWork()
由于两个DoWork()
都在计时器中运行,因此如果发生异常,我将无法捕获它。如果我可以修改PluginA和PluginB,但可以避免,则很容易避免。
关于如何避免此问题的任何建议?预先感谢。
以下代码是真实代码的过度简化:
public class MyService
{
private PluginA pA = new PluginA();
private PluginB pB = new PluginB();
// Windows Service runs Start when the service starts. It must return ASAP
public void Start()
{
// try..catch doesn't capture PluginB's exception
pA.Start();
pB.Start();
}
// Windows Service runs Stop when the service Stops. It must return ASAP
public void Stop()
{
pA.Stop();
pB.Stop();
}
}
// I have no control over how this is developed
public class PluginA
{
private Timer _timer;
public void Start()
{
_timer = new Timer(
(e) => DoWork(),
null,
TimeSpan.Zero,
TimeSpan.FromSeconds(10));
}
private void DoWork()
{
File.AppendAllText(
"C:/log.txt",
"hello" + Environment.NewLine);
}
public void Stop()
{
_timer.Change(Timeout.Infinite, 0);
}
}
// I have no control over how this is developed
public class PluginB
{
private Timer _timer;
public void Start()
{
_timer = new Timer(
(e) => DoWork(),
null,
TimeSpan.Zero,
TimeSpan.FromSeconds(10));
}
private void DoWork()
{
File.AppendAllText(
"C:/log.txt",
"Goodbye" + Environment.NewLine);
throw new Exception("Goodbye");
}
public void Stop()
{
_timer.Change(Timeout.Infinite, 0);
}
}