2016-04-28 6 views
5

Ich habe die folgende MethodeWie Speicher-Stream, der in Aufgabe?

public void Write() { 
    var tasks = new List<Task>(); 
    while(...) { 
     var memoryStream = new MemoryStream(...); 
     var task = _pageBlob.WritePagesAsync(memoryStream, ...); 
     tasks.Add(task); 
    }  
    Task.WaitAll(tasks.ToArray()); 
} 

Wie richtig memoryStream entsorgen, dass in Task? Ich muss das Objekt memoryStream entsorgen, wenn die Aufgabe abgeschlossen ist.

+3

Sie müssen MemoryStream nicht entfernen, aber die Frage ist immer noch gültig. Es kann für die Codequalität gut sein, es in 'using' zu bringen. – usr

+0

Wie kann ich es in ein 'using' setzen? Ich brauche 'Task.WaitAll (tasks.ToArray());' nach einer Schleife – Anatoly

+0

Hinzufügen 'using' zu dem Code einer der Antworten. Sie hätten es zuerst benutzen sollen, aber vielleicht haben sie es einfach nicht gestört. – usr

Antwort

2

Spl es Ihre while Schleifenkörper in eine separate async Methode aus:

private async Task WriteAsync(...) 
{ 
    using (var memoryStream = new MemoryStream(...)) 
    { 
    await _pageBlob.WritePagesAsync(memoryStream, ...); 
    } 
} 

Dann wird Ihre neue Methode verwenden:

public void Write() { 
    var tasks = new List<Task>(); 
    while(...) { 
    tasks.Add(WriteAsync(...)); 
    }  
    Task.WaitAll(tasks.ToArray()); 
} 

Auf einer Seite zur Kenntnis, auf asynchronen Code Blockierung (Task.WaitAll) ist nicht generell eine gute Idee . Ein natürlicherer Ansatz besteht darin, es asynchron zu halten:

public async Task WriteAsync() { 
    var tasks = new List<Task>(); 
    while(...) { 
    tasks.Add(WriteAsync(...)); 
    }  
    await Task.WhenAll(tasks); 
} 
+2

Ja, das ist der sauberste Weg. Es gibt keinen Grund, etwas anderes zu tun. – usr

+0

Wann entsorgen wir einen Stream? – Anatoly

+0

@Anatoly: Der Stream befindet sich am Ende des 'using' Blocks. –

3

Sie haben zwei Möglichkeiten:

1-kapseln ganzen Prozess innerhalb einer Aufgabe:

while(...) { 

    var task = Task.Run(async() => { 

     var memoryStream = new MemoryStream(...); 
     var res = await _pageBlob.WritePagesAsync(memoryStream, ...); 
     memoryStream.Dispose(); 

    }); 

    tasks.Add(task); 
}  

2-Nutzung eine Fortsetzung:

while(...) { 
    var memoryStream = new MemoryStream(...); 
    var task = _pageBlob.WritePagesAsync(memoryStream, ...) 
       .ContinueWith((PrevTask) => memoryStream.Dispose()); 

    tasks.Add(task); 
}  
+0

Nun, es gibt eine Menge mehr Möglichkeiten, dies zu tun (pro Beispiel mit einer externen Liste , wo Sie die Strähnen halten und nach dem WaitAll entsorgen), aber diese beiden Wege sind diejenigen, die das Async-Framework verwenden. – Gusman

+0

Ich muss das 'memoryStream'-Objekt entsorgen, wenn die Aufgabe beendet ist. Ich möchte keine 'async/await'-Schlüsselwörter haben. Wie fügt man fortsetzung hinzu und dispose stream drinnen? – Anatoly

+0

Verwenden Sie den zweiten Code ... das ist es. – Gusman

0

ich so etwas tun würde:

public void Write() 
{ 
    var tasks = new List<Task>(); 
    while (...) 
    { 
     var memoryStream = new MemoryStream(...); 
     var task = WritePagesAsync(memoryStream, ...); 
     tasks.Add(task); 
    } 
    Task.WaitAll(tasks.ToArray()); 
} 

private async Task WritePagesAsync(MemoryStream memoryStrem, ...) 
{ 
    await _pageBlob.WritePagesAsync(memoryStrem); 
    memoryStrem.Dispose(); 
} 
Verwandte Themen