none
Блокирование метода Finalize RRS feed

  • Вопрос

  • Добрый день, пишется многопоточное приложение под с#. В приложении имется необходимость в потоке который бы через определенное время проверял некоторые уловия. Время жизни потока определенно пользователе, т.е. поток может выполняться как до конца программы так и завершаться во время ее работы.
    Под эти эти цели был создан специальный класс который, который содержит в себе поток.

    	public class SSimpleThread
    	{
     		private ManualResetEvent Event;
    		private Thread MaitThreadTh;
    		private void maitThreadMethod()
    		{
    			Event.WaitOne();
    
    		}
    		public SSimpleThread()
    		{
    			MaitThreadTh=new Thread(maitThreadMethod);
    			Event=new ManualResetEvent(false);
    			MaitThreadTh.Start();
    		}
    		public void Dispose()
    		{
    			MaitThreadTh.Abort();
    			MaitThreadTh.Join();
    			GC.SuppressFinalize(this);
    		}
    		~SSimpleThread()
    		{
    			MaitThreadTh.Abort();
    			MaitThreadTh.Join();
    		}
    как видо что класс простой, и поток метода ни чего не делает кроме как бесконечно ждет.
    В примере программы создается объект данного класса, а по истечении программа завершается
    		static void Main(string[] args)
    		{
    			SSimpleThread SimpleThread=new SSimpleThread();
    			Thread.Sleep(1000);
    			//SimpleThread.Dispose();
    		}
    
    
    Вот тут собственно и возникает блокировка метода Finalize. Программа не может завершиться вообще (в деструктор отладчик даже не заходит), но при использовании метода Dispose программа корректно завершается. В чем же дело и как корректно реализовать деструктор, у классов в которых есть рабочие потоки?
    • Перемещено Siddharth Chavan 1 октября 2010 г. 21:56 MSDN Forums Consolidation (От:Visual C#)
    18 октября 2009 г. 11:17

Ответы

  • Корректно - не использовать Finalize для остановки управляемых потоков. Object.Finalize предназначен для освобождения неуправляемых ресурсов. MaitThreadTh с большой верятностью будет неактуален к моменту вызова финализатора.
    Самый простой вариант - выставить IsBackground у потока, если он может быть убит без последствий. Тогда он не будет препятствовать завершению приложения.

    • Предложено в качестве ответа I.Vorontsov 19 октября 2009 г. 5:49
    • Помечено в качестве ответа I.Vorontsov 3 ноября 2009 г. 8:20
    18 октября 2009 г. 13:29