2016-11-15 4 views
5

コードこのように、私は仕事の多くをTask.Runに入れたいと思っていますが、usingステートメントが期待どおりに機能するかどうかはわかりません。usingステートメント内でTask.Runを呼び出すことはできますか?

using(MemoryStream ms = new MemoryStream()) 
{ 
    Task.Run(() => 
    { 
     /* capture ms and process the stream */ 
    } 
} // Will ms will be disposed here automatically? 

ありがとうございます。

+0

本当の問題は、「私は 'await'をElideのことができています'using'文の中に?"これは本当に 'Task.Run'とは関係ありません。 –

答えて

5

いいえ - ストリームの処理は、タスクの実行が完了する前に実行される可能性があります。タスクの終了時に処分を行うことができれば、それを使用することをお勧めします。

var ms = new MemoryStream(); 
Task.Run(() => 
{ 
    /* capture ms and process the stream */ 

    // Dispose of the stream manually when you are done 
    ms.Dispose(); 
} 

タスク外でメモリストリームを使用している場合は、処理後に使用するリスクがあります。可能であれば、タスク内のストリームのみを使用し、結果を別の場所に保存してください。

Task.Run(() => 
{ 
    using(var ms = new MemoryStream()) 
    { 
     /* capture ms and process the stream */ 
    } 
} 
+0

ありがとう、私はTask.Runの前に "待って"置くと、それはすべてのものが正しく働くようになると思いますか? – codewarrior

+0

うん@ - @Letseatunchにも同様の例があります –

+0

disposeが2回呼び出されるかどうかは関係ありません – Mick

3

ストリームは、タスクが完了する前に閉じられて処理される可能性が非常に高いです。この次は、説明ObjectDisposedExceptionをスロー:

using(MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes("abc"),0,3)) 
{ 
    Task.Run(() => 
    { 
     Thread.Sleep(100); 
     ms.Read(new byte[3], 0, 3); 
    }); 
} 

あなたが好きタスクを待つことができタスク閉鎖にusingステートメントを移動したりできます。

using(MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes("abc"),0,3)) 
{ 
    await Task.Run(() => 
    { 
     Thread.Sleep(100); 
     var bytes = new byte[3]; 
     ms.Read(bytes, 0, 3); 
     Console.WriteLine(Encoding.ASCII.GetString(bytes)); 
    }); 
} 
関連する問題