473,395 Members | 1,677 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

How can I clean up a long-running task before the process ends?

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

Nov 16 '05 #1
2 2413
For a service you might be able to override the OnStop method. But it is
difficult to hook the system when a process if simply forced to terminate.

You might want to cleanup when the process starts rather then when it is
terminated. You can still do normal housecleaning upon normal termination,
but also cleanup when starting since you do not know how it was terminated.

"Jeffrey Palermo, MCAD.Net" <je************@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
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().Fu
llName, 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

Nov 16 '05 #2
I'll post my solution to this problem so that anyone searching this
thread isn't left hanging.

I send work to the Threadpool, so when the Threadpool executes my
method, I add that thread to an ArrayList and remove it when finished.
That way I have a list of current threadpool thread I'm using. When I
need to abort, I just loop through them all and call Abort() and Join()
on each thread. It sends a ThreadAbortException down the thread, and
my normal cleanup code can execute. Join() blocks and waits until that
thread has exited before returning, so I delay the shutting down of my
service until all worker threads have exited. In this way, nothing is
left hanging. Here is my Controller class.

public class Controller
{
public ArrayList threads = new ArrayList();

public Controller(){
// Just so we can see the activity.
Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
}
public void DoWork(){
try{
// Three might be running at the same time.
for(int i = 0; i < 3; i++){
ThreadPool.QueueUserWorkItem(new WaitCallback(Execute));
}
Thread.Sleep(20000);
Trace.WriteLine(threads.Count, this.ToString());
}finally{
foreach(Thread t in threads){
t.Abort();
t.Join();
}
}
}
private void Execute(object state){
threads.Add(Thread.CurrentThread);

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{
threads.Remove(Thread.CurrentThread);
if(domain != null)
AppDomain.Unload(domain);
}
}
}

Best regards,
Jeffrey Palermo
Blog: http://www.jeffreypalermo.com

Nov 16 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Jason | last post by:
I have a number of arrays that are populated with database values. I need to determine which array has the highest ubound out of all the arrays. The array size will always change based on the...
1
by: Matt Garman | last post by:
I've got some code that generates a report for the user. The report is shown with explanatory verbage. The text is relatively long, and also has some simple formatting (paragraphs, bulleted...
17
by: Christopher Benson-Manica | last post by:
Yesterday I changed some code to use std::vectors and std::strings instead of character arrays. My boss asked me today why I did it, and I said that the code looks cleaner this way. He countered...
3
by: kayjean | last post by:
Hi. I have a small test.cc >> g++ -o test test.cc (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) >> phase 1 (VSZ RSS 50844 47748 ) >> phase 2 (VSZ RSS 50844 47748 ) >> phase 3 (VSZ RSS...
7
by: Felix Kater | last post by:
Hi, when I need to execute a general clean-up procedure (inside of a function) just before the function returns -- how do I do that when there are several returns spread over the whole function?...
4
by: Jeeran | last post by:
We use an ISAPI filter to convert long urls into short clean ones. For example: "Site.com/user/john/" Is re-written as: "Site.com/user/userinfo.aspx?uid=john" Now, "userinfo.aspx" contains a...
1
by: Michael | last post by:
I have a solution for this, but it feels wrong. If anyone could offer a better one, I'm all ears. (Or technically, eyes.) Basically, I have a bunch of classes. For concreteness, one is a...
7
by: siggi | last post by:
Hi all, when I do >>>sys.path in IDLE (winXP), i get a horrendously long list of paths, paths I may have used during a lot of trials and errors. How can I clean up sys.path? I mean, trim it of...
232
by: robert maas, see http://tinyurl.com/uh3t | last post by:
I'm working on examples of programming in several languages, all (except PHP) running under CGI so that I can show both the source files and the actually running of the examples online. The first...
1
by: sarahbanker | last post by:
ok, so I've inherited a nightmare of an Access 03 database, and trying to clean up the admin and maintainence side of it. It's being used as a tool to provide revised credit card limits based on...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.