I have some classes that control file processing in c#. The files come
from a mainframe and may take some time for each to process. I use the
Threadpool to process multiple files at once. Each instance of the
file processor is spawned in its own AppDomain to isolate it (I'm using
a separate AppDomain for a valid reason, so this thread isn't to
discuss that). My process is a Windows service, but I can duplicate
this problem as a regular console project.
When the process is terminated (or the Windows service stopped), any
files currently processing are stopped midway even though there is code
in my finally block. I've included the relavent classes below:
The main executable has these methods:
static void Main(string[] args) {
// call test method here.
RunController();
Console.WriteLine("hit enter to exit");
Console.ReadLine();
}
static void RunController(){
Controller ctrl = new Controller();
ctrl.DoWork();
}
And then the Controller class:
using System;
using System.Diagnostics;
using System.Reflection;
using System.Threading;
namespace ConsoleTestHarness
{
public class Controller
{
public Controller(){
// Just so we can see the activity.
Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
}
public void DoWork(){
// Three might be running at the same time.
for(int i = 0; i < 3; i++){
ThreadPool.QueueUserWorkItem(new WaitCallback(Execute));
}
}
private void Execute(object state){
AppDomainSetup setup = null;
AppDomain domain = null;
try{
setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
domain = AppDomain.CreateDomain("Processor", null, setup);
Processor proc =
(Processor)domain.CreateInstanceAndUnwrap(Assembly .GetExecutingAssembly().FullName,
typeof(Processor).FullName);
proc.Process();
}finally{
if(domain != null)
AppDomain.Unload(domain);
}
}
}
}
And the processor class:
using System;
using System.Diagnostics;
namespace ConsoleTestHarness
{
[Serializable()]
public class Processor
{
public void Process(){
try{
Trace.WriteLine("Beginning Processing", this.ToString());
// Simulate a long-running process.
System.Threading.Thread.CurrentThread.Suspend();
}finally{
Trace.WriteLine("Finished", this.ToString());
// Close out database record an other cleanup.
}
}
}
}
I've stripped away irrelevant code. The code in the finally blocks
doesn't run, so files are left half-processed.
Has anyone else out there tackled a problem like this? Stopping a
service or terminating an EXE gracefully?
Best regards,
Jeffrey Palermo
http://www.jeffreypalermo.com