views:

217

answers:

7

I'm trying to find out whether there is a way to reliably determine when a managed thread is about to terminate. I'm using a third-party library that includes support for PDF documents and the problem is that in order to use the PDF functionality, I have to explicitly initialize the PDF component, do the work, then explicitly uninitialize the component before the thread terminates. If the uninitialize is not called, exceptions are thrown because unmanaged resources are not being released correctly. Since the thread class is sealed and has no events, I have to wrap the thread instance into a class and only allow instances of this class to do the work.

I should point out that this is part of a shared library used by multiple Windows applications. I may not always have control of threads making calls into this library.

Since a PDF object may be the output of a call to this library, and since the calling thread may do some other work with that object, I don't want to call the cleanup function immediately; I need to try to do it right before the thread terminates. Ideally I'd like to be able to subscribe to something like a Thread.Dispose event, but that's what I'm missing.

+1  A: 

I think you can use an [Auto|Manual]ResetEvent which you will set when the thread terminates

Eric
+2  A: 

Catch the ThreadAbortExcpetion.

http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception.aspx

Nick Berardi
There will only be a ThreadAbortException raised if the thread dies via Abort, which is not the case most of the time.
McKenzieG1
+3  A: 

You don't want to wrap System.Thread per se - just compose it with your PDFWidget class that is doing the work:

class PDFWidget
{
    private Thread pdfWorker;
    public void DoPDFStuff()
    {
        pdfWorker = new Thread(new ThreadStart(ProcessPDF));
        pdfWorker.Start();
    }

    private void ProcessPDF()
    {
        OtherGuysPDFThingie pdfLibrary = new OtherGuysPDFThingie();
        // Use the library to do whatever...
        pdfLibrary.Cleanup();
    }
}

You could also use a ThreadPool thread, if that is more to your taste - the best choice depends on how much control you need over the thread.

McKenzieG1
A: 

Wouldn't you just wrap your PDF usage with a finally (if it's a single method), or in an IDisposable?

Mark Brackett
A: 

Check the Powerthreading library at http://wintellect.com.

Drakiula
+1  A: 

what about calling a standard method in async mode? e.g

//declare a delegate with same firmature of your method
public delegete string LongMethodDelegate ();

//register a callback func
AsyncCallback callbackFunc = new AsyncCallback (this.callTermined); 

//create delegate for async operations
LongMethodDelegate th = new LongMethodDelegate (yourObject.metyodWichMakeWork);

//invoke method asnync.
// pre last parameter is  callback delegate.
//the last parameter is an object wich you re-find in your callback function. to recovery return value, we assign delegate itSelf, see "callTermined" method
longMethod.beginInvoke(callbackFunc,longMethod);   

//follow function is called at the end of thr method
public static void callTermined(IAsyincResult result) {
LongMethodDelegate method  = (LongMethodDelegate ) result.AsyncState;  
string output = method.endInvoke(result);
Console.WriteLine(output);
}

See here form more info: http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx

stefano m
+1  A: 

There are many ways you can do this, but the most simple one is to do like McKenzieG1 said and just wrap the call to the PDF library. After you've called the PDF-library in the thread you can use an Event or ManualResetEvent depending on how you need to wait for the thread to finish.

Don't forget to marshal event-calls to the UI-thread with a BeginInvoke if you're using the Event approach.

Patrik