2011-12-16 11 views
4

スコープを使い果たし、タスクが完了する前にガベージコレクタがそれを取り除くことを決定したら、ローカルのタスク参照はどうなりますか?この例では廃棄されたタスクはどうなりますか?

/// <summary> 
/// Web service operation to start a large batch asynchronously 
/// </summary>  
public StartBatchResponseMessage StartBatch(StartBatchRequestMessage request) 
{ 
    Task t = Task.Factory.StartNew(DoWork); 
    return new StartBatchResponseMessage(); 
} 

private void DoWork() 
{ 
    // Implement solving world hunger here. 
} 

ウィルDoWork常に完全な:それはサービスコールの実装のこの種を作るためにも安全かどう

は基本的に私は聞いていますのよ?ガベージコレクタがTaskインスタンス変数を破棄することを決定したとしても、

もしそうでなければ、この種の機能をより安全に実装する方法は何ですか?

+0

「ディスポジション」という言葉の使い方には注意してください。 'IDisposable'パターンと混同しないでください。 – Gusdor

答えて

9

はい、実行されます。コードを逆コンパイルすると、Task.Factory.StartNewへの呼び出しがTask.InternalStartNewと表示され、Task.ScheduleAndStart(false)が呼び出されます。

task.m_taskScheduler.QueueTask(this),これは、MSDNに従って、内部構造にタスクを追加します。もちろん、ガベージコレクションを停止します。あなたとまったく同じです。

+0

これは何が起こるかについてのさらに深い説明です。そのように動作すると思ったが、確かに傷つくことはない。ありがとう!これは、あなたがusingステートメント内でタスクを実行するように警告されていない理由ですか? – nicojs

+0

それは面白いです - 私はタスクがIDisposableを実装して気づいていなかったことを認めて恥ずかしいです。それは、それがポイントの全体が非同期であるため、usingステートメントに入れるのは確かに機能しません。処理が完了していないか、またはキャンセルされたときにdisposeを呼び出すと、(タスクt = newTask){}を使用して、使用ブロックを終了する際に例外がスローされるように、例外がスローされます(ただし、またはキャンセルされた) –

+0

これは、特定のジョブの実行時にタスクが完了したことを確認するためにusingステートメントを使用したり、例外をスローすることができることを示唆しています。いくつかのケースで役に立つかもしれません..私は推測します。 – nicojs

1

はい、タスクは常に完了します。ガベージコレクタは、タスクが実行されている間、関連する部分に移動することはありません。

3

常識、あなたは知っています。タスクライブラリは何とかあなたのメソッドを呼び出さなければならないので、参照を保持する必要があります。それ以外の場合は呼び出すことができませんでした。したがって、明らかに、この参照はガベージコレクションを防ぎます。

基本的に「タスク」は、内部実行エンジンも参照を持つ必要があるタスクオブジェクトへのポインタです。それ以外の場合は実行されません。

したがって、t変数以外の参照があるので、それは破棄されません。

関連する問題