2009-06-23 10 views
15

使用ブロックを終了して解放されたオブジェクトのメソッドを実行している場合、スレッドはどうなりますか?
例:スコープ付きオブジェクト上でまだスレッドが実行中のusing()ブロックを終了するC#

 
    using (SomeObject obj = new SomeObject()) 
    { 
     obj.param = 10 ; 
     Thread newThread = new Thread(() => { obj.Work(); }); 
     newThread.Start(); 
    } 
    ... 

obj.Work()は新しいスレッドで実行されているが、OBJは、ブロックの終了を使用した場合、通常はリリースになるだろうIDisposableをオブジェクトです。使用ブロックが終了してもスレッドが実行を継続するとどうなりますか?スレッドが完了した後にのみオブジェクトが破棄されますか?またはスレッドが壊れますか?

ありがとうございました。

+0

スレッドの外側でusingステートメントを使用するのではなく、スレッド内に配置します。 スレッドnewThread =新しいスレッド(()=> {; obj.Work();} は= 10(SomeObjectのOBJ =新しいSomeObjectの()){ obj.param用い})。 newThread.Start(); – Relster

答えて

4

IDisposableは単なるパターンであり、オブジェクトに関連付けられたメモリを解放しないことに注意してください。この場合、usingブロックの終了はobj.Disposeを呼び出し、objを使用している他のスレッドは引き続き実行されます。

これは、obj'sの状態が変更される可能性があります(他のスレッドがそれを使用している間に変更される可能性があります)。これはすべてDisposeメソッドの実装方法によって異なります。言うまでもなく、IDisposable、スレッド、およびusingステートメントのこのアプリケーションは、せいぜい問題になります。

1

メインブロックで使用ブロックが終了すると、そのオブジェクトが.Dispose()され、あらゆる種類の面倒な同時実行の問題が発生する可能性があります。ただし、オブジェクトはガベージコレクトされません。無効な状態で残っていますが、これは.Dispose()の実装によって異なります。

11

面白いことが起こります。

具体的には、SomeObjectのdisposeメソッドは、Workが呼び出される前または後のいずれかに呼び出されます。これは、そのポイントで実行するようスケジュールされている場合とされていない場合があります。

その後、SomeObjectの処理メソッドが何をするかによって異なります。たとえば、 'Work'で使用されていないSqlConnectionをリリースすると、問題は発生しません。 SomeObjectがそれが破棄されていないことを期待している場合は、おそらくそのスレッドに例外がスローされます。

+0

興味深いもの、良いもの。 – Groo

+0

なんらかの理由で、私はイタリア人職業のMos Defを思い浮かべます。「私は悪い経験をしました」 –

2

オブジェクトは、ブロックの最後にDisposeを呼び出します。それは実行を続けますが、Disposeは接続を閉じるなどと考えて不安定になります。objが何かが使用中であるかどうかをチェックして後で終了するように設定することは可能ですが、これを処理するオブジェクトを記述しました。

関連する問題