2016-05-27 5 views
0

У меня есть класс, который реализует IDisposable. Класс содержит нить и нить закрыта в методе Dispose с помощью Thread.Join(...)Thread.Join принудительно закрывает нить на конце приложения

Мой вопрос, однако, что если я бегу моего класса, как это:

static void Main(string[] args) 
{ 
    var class = new MyClass(); 
    class.Run(); 
} 

, когда приложение закрывается, она принудительно закрывает поток не дожидаясь его завершения.

Однако, если я бегу это так:

static void Main(string[] args) 
{ 
    using (var class = new MyClass()) 
    { 
     class.Run(); 
    } 
} 

нить заканчивает то, что она начала и заканчивается изящно. Что такое оператор using, который позволяет потоку завершить выполнение?

Моя догадка такова, что с первым методом, поскольку приложение вышло, оно принудительно закрывает поток, не дожидаясь его завершения. Тем не менее, в блоке использования приложение все еще работает, поэтому у него есть время, чтобы закрыть поток, а затем выйти из приложения.

Если моя догадка верна, вы можете сообщить мне, почему приложение не дожидалось завершения потока до закрытия?

Edit:

~ElasticBase() 
{ 
    Dispose(false); 
} 

public virtual void Initialize() 
{ 
    workerThread = new Thread(ProcessData) 
    { 
     Name = "ElasticBase thread", 
     IsBackground = true 
    }; 

    IsInitialized = true; 
} 

public virtual void Shutdown() 
{ 
    if (workerThread.IsAlive) 
    { 
     IsInitialized = false; 
     lock (syncObject) 
     { 
      if (!workerThread.Join(10000)) 
      { 
       workerThread.Abort(); 
      } 
      workerThread = null; 
     } 
    } 
} 

public void Dispose() 
{ 
    Dispose(true); 
    GC.SuppressFinalize(this); 
} 

protected void Dispose(bool calledFromDispose) 
{ 
    Shutdown(); 
} 

Как вы можете видеть, с указанным кодом. Метод Shutdown вызывается в Dispose. Если я НЕ ВЫПОЛНИТЬ Утилиту явно, и я НЕ использую используемый блок, метод Thread.Join закрывается без завершения. Однако, если я вызываю Dispose explicity или использую блок using, вдруг Thread.Join работает так, как ожидалось. Зачем?

TLDR;

Когда Dispose вызывается через финализатор, Thread.Join не ждет завершения. Когда утилита явно вызывается (посредством ручного вызова ее или с помощью оператора using), Thread.Join ждет завершения.

+0

http://stackoverflow.com/questions/212198/what-is-the-c-sharp-using-block-and-why-should-i-use-it –

+1

Является ли поток в вашем классе фоновым потоком ? Если это поток переднего плана, то в обоих случаях вызывающий поток должен ждать окончания дочернего потока. Если это фоновый поток, то Thread.Join() заставляет основной поток ждать завершения дочернего потока. В противном случае он заканчивается без ожидания дочерних потоков. – PiotrWolkowski

+0

@PiotrWolkowski Это фоновый поток. Но когда я меняю его на передний план.Он выходит еще быстрее:/ – CodingMadeEasy

ответ

-1

Вы пропустили две части информации:

  • Thread.Join не закрывает поток. Скорее, он ждет, пока поток завершит выполнение.
  • using - всего лишь синтаксический сахар для вызова метода Dispose в блоке try/finally.

Чтобы сделать это просто, ваш код эквивалентен:

MyClass class = null; 

try 
{ 
    class = new MyClass(); 
    class.Run(); 
} 
finally 
{ 
    if (class != null) 
    { 
     class.Dispose(); 
    } 
} 

Поскольку ваш метод Dispose вызывает Thread.Join, который, в свою очередь ждет нить для завершения выполнения, приложение не выходит преждевременно.

+0

Но как только Thread.join вызывается в моем первом примере. Нить не заканчивается. Это потому, что приложение закрыто? Это приложение, которое принудительно закрывает поток? Также я знаю, что использует, но как только я его использую, поток заканчивается исполнением. Даже если я не использую оператор using, но я вызвал класс.Dispose() до выхода приложения, поток завершит выполнение. Но когда утилита вызывается финализатором, поток резко закрывается. – CodingMadeEasy

+0

@CodingMadeEasy В первом коде, который вы опубликовали, 'Dispose' называется нигде –

+0

@KoolKiz Я знаю, что не знаю. Я просто пытаюсь заявить, что когда утилита явно вызвана (с использованием или методом Dispose). Поток заканчивает выполнение. Однако, если я не использую блок использования, и я явно не вызываю .Dispose(). Приложение принудительно выходит, не заканчивая нить. – CodingMadeEasy