有没有办法确定.NET线程何时终止?

时间:2022-02-27 21:01:43

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.

我试图找出是否有办法可靠地确定托管线程何时即将终止。我正在使用包含对PDF文档的支持的第三方库,问题是为了使用PDF功能,我必须显式初始化PDF组件,完成工作,然后在线程终止之前显式取消初始化组件。如果未调用uninitialize,则抛出异常,因为未正确释放非托管资源。由于线程类是密封的并且没有事件,我必须将线程实例包装到类中,并且只允许此类的实例执行工作。

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.

我应该指出,这是多个Windows应用程序使用的共享库的一部分。我可能无法控制线程调用此库。

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.

由于PDF对象可能是对此库的调用的输出,并且由于调用线程可能会对该对象执行一些其他工作,因此我不想立即调用清理函数;我需要尝试在线程终止之前做到这一点。理想情况下,我希望能够订阅Thread.Dispose事件,但这就是我所缺少的。

7 个解决方案

#1


3  

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

您不希望自己包装System.Thread - 只需将其与正在执行工作的PDFWidget类组合:

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.

您也可以使用ThreadPool线程,如果更符合您的口味 - 最佳选择取决于您对线程需要多少控制权。

#2


1  

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

我想你可以使用线程终止时设置的[Auto | Manual] ResetEvent

#3


1  

Catch the ThreadAbortExcpetion.

捕获ThreadAbortExcpetion。

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

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

#4


1  

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

请参阅此处表单更多信息:http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx

#5


1  

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.

有很多方法可以做到这一点,但最简单的方法是像McKenzieG1那样说,只需将调用包装到PDF库中。在线程中调用PDF库后,您可以使用Event或ManualResetEvent,具体取决于您需要等待线程完成的方式。

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

如果您正在使用Event方法,请不要忘记使用BeginInvoke封送对UI线程的事件调用。

#6


0  

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

难道你不是只用一个finally(如果它是一个单一的方法)或在IDisposable中包装你的PDF用法吗?

#7


0  

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

查看位于http://wintellect.com的Powerthreading库。

#1


3  

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

您不希望自己包装System.Thread - 只需将其与正在执行工作的PDFWidget类组合:

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.

您也可以使用ThreadPool线程,如果更符合您的口味 - 最佳选择取决于您对线程需要多少控制权。

#2


1  

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

我想你可以使用线程终止时设置的[Auto | Manual] ResetEvent

#3


1  

Catch the ThreadAbortExcpetion.

捕获ThreadAbortExcpetion。

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

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

#4


1  

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

请参阅此处表单更多信息:http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx

#5


1  

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.

有很多方法可以做到这一点,但最简单的方法是像McKenzieG1那样说,只需将调用包装到PDF库中。在线程中调用PDF库后,您可以使用Event或ManualResetEvent,具体取决于您需要等待线程完成的方式。

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

如果您正在使用Event方法,请不要忘记使用BeginInvoke封送对UI线程的事件调用。

#6


0  

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

难道你不是只用一个finally(如果它是一个单一的方法)或在IDisposable中包装你的PDF用法吗?

#7


0  

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

查看位于http://wintellect.com的Powerthreading库。