2016-05-27 12 views
0

私はIDisposableを実装するクラスを持っています。クラスはスレッドが含まれており、スレッドがThread.Join(...)Thread.Joinはアプリケーション終了時に強制的にスレッドを閉じます。

私の問題は、しかし、私はこのような私のクラスを実行する場合ということです使用してDisposeメソッド内で閉じている:

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

アプリケーションが閉じたときに、それが強制的にスレッドをクローズしますそれが実行を完了するのを待たずに。私はこのようにそれを実行した場合

しかし、:

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

スレッドが開始され、正常に終了するもの終了します。使用しているステートメントは、スレッドの実行を完了させるために何をしていますか?

最初の方法では、アプリケーションが終了したため、スレッドが終了するのを待たずに強制的にスレッドを閉じます。ただし、usingブロックの下では、アプリケーションはまだ実行されているため、スレッドを閉じてからアプリケーションを終了する時間があります。

私の勘違いが正しい場合は、アプリケーションが終了する前に終了するスレッドでアプリケーションが待機しない理由を教えてください。

編集:

~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で呼び出されます。明示的にDisposeを呼び出さず、usingブロックを使用しない場合、Thread.Joinメソッドは終了せずに終了します。しかし、Disposeを明示的にDisposeまたはUsingブロックを使用すると、突然Thread.Joinが期待どおりに動作します。どうして?

TLDR;

Disposeがファイナライザによって呼び出されると、Thread.Joinは完了を待たずに終了します。 disposeを明示的に呼び出すと(手動で呼び出すか、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

あなたは、2つの情報を逃している:

  • Thread.Joinは、スレッドを閉じません。むしろ、スレッドが実行を終了するまで待機します。
  • usingは、try/finallyブロックのDisposeメソッドを呼び出すための単なる構文糖です。

それを簡単にする、あなたのコードは同等です:あなたDisposeメソッドが実行を終了するスレッドの順番を待ちで、アプリケーションが途中で終了しないThread.Joinを呼び出すので

MyClass class = null; 

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

+0

しかし、最初の例ではThread.joinが呼び出されています。スレッドは実行を終了しません。アプリケーションが閉じられているからですか?スレッドを強制的に閉じるアプリケーションですか? また、使用方法はわかりますが、使用するとスレッドの実行が終了します。 usingステートメントを使用していなくても、アプリケーションが終了する前にclass.Dispose()を呼び出しても、スレッドは実行を終了します。しかし、ファイナライザによってdisposeが呼び出されると、スレッドは突然終了します。 – CodingMadeEasy

+0

@CodingMadeEasyあなたが投稿した最初のコードでは、「Dispose」はどこでも呼び出されていません。 –

+0

@KoolKiz私は私が知っていないことを知っています。私は単に、disposeが明示的に呼び出されたとき(usingまたはDisposeメソッドを使用して)呼び出されるようにしようとしています。スレッドは実行を終了します。しかし、もし私がusingブロックを使用していないと、私は明示的に.Dispose()を呼び出さない。アプリケーションはスレッドを終了させることなく強制的に終了します。 – CodingMadeEasy

関連する問題