2016-11-15 1 views
5

Code wie folgt, ich möchte den Großteil der Arbeit in eine Task.Run setzen, aber ich bin mir nicht sicher, ob die using-Anweisung immer noch wie erwartet funktioniert.Ist es OK, Task.Run intern mit Anweisung aufzurufen?

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

Danke.

+0

Die eigentliche Frage ist: „Ich kann elide' await' in einem 'using' Statement?" Es hat wirklich nichts mit 'Task.Run' zu tun. –

Antwort

5

Nein - Die Stream-Entsorgung kann ausgeführt werden, bevor Ihre Task beendet wurde. Es wäre besser, die Verwendung innerhalb der Aufgabe zu platzieren, wenn dies möglich ist, oder die Entsorgung am Ende der Aufgabe manuell durchzuführen.

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

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

Beachten Sie, wenn Sie den Speicher-Stream verwenden außerhalb der Task, dann Sie die Gefahr der Verwendung es ausführen, nachdem er angeordnet ist. Wenn Sie können, verwenden Sie nur den Stream in der Task und speichern Sie die Ergebnisse an anderer Stelle.

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

Danke, ich denke, wenn ich vor Task.Run "warten" würde, würde das ganze Dinge funktionieren lassen, richtig? – codewarrior

+0

Yep - @Letseatlunch hat auch ein Beispiel dafür –

+0

Es sollte egal sein, wenn dispose zweimal aufgerufen wird – Mick

3

Der Datenstrom wird höchstwahrscheinlich geschlossen und entsorgt, bevor die Aufgabe abgeschlossen ist. Das folgende wirft einen ObjectDisposedException:

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

Sie die Anweisung using in die Aufgabe Schließung bewegen konnte oder Sie die Aufgabe erwarten kann wie:

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)); 
    }); 
} 
Verwandte Themen