2016-04-28 16 views
5

Mam następujący sposóbJak usunąć strumień pamięci w zadaniu?

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()); 
} 

Jak prawidłowo utylizować memoryStream że w Task? Po zakończeniu zadania muszę pozbyć się obiektu memoryStream.

+3

Nie musisz likwidować MemoryStream, ale pytanie jest nadal ważne. Może to być dobre dla jakości kodu, aby umieścić go w 'użyciu'. – usr

+0

Jak mogę umieścić go w 'użyciu'? Muszę zrobić 'Task.WaitAll (tasks.ToArray());' po pętli – Anatoly

+0

Dodaj 'using' do kodu jednej z odpowiedzi. Powinni go wykorzystać, ale może po prostu nie zawracali sobie głowy. – usr

Odpowiedz

2

Spl to swoje ciało while pętla do osobnego sposobu async:

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

Następnie za pomocą nowej metody:

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

Na marginesie, blokując na kod asynchroniczny (Task.WaitAll) generalnie nie jest dobrym pomysłem . Bardziej naturalnym podejściem jest zachowanie asynchroniczności:

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

Tak, to najczystszy sposób. Nie ma powodu, aby robić cokolwiek innego. – usr

+0

Kiedy dysponujemy strumieniem? – Anatoly

+0

@Anatoly: Strumień jest umieszczony na końcu bloku 'using'. –

3

Masz dwie opcje:

1-enkapsulacji cały proces wewnątrz zadania:

while(...) { 

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

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

    }); 

    tasks.Add(task); 
}  

2-użyć Kontynuacja:

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

    tasks.Add(task); 
}  
+0

Cóż, istnieje mnóstwo sposobów na zrobienie tego (na przykład z zewnętrzną listą , gdzie przechowujesz strumienie i pozbywasz się ich po WaitAll), ale te dwa sposoby są tymi, które używają struktury Async. – Gusman

+0

Potrzebuję usunąć obiekt 'memoryStream' po zakończeniu zadania. Nie chcę mieć słów kluczowych "asynchronicznych/oczekujących". Jak dodać kontynuację i umieścić w niej strumień? – Anatoly

+0

użyj drugiego kodu ... to właśnie robi. – Gusman

0

chciałbym zrobić coś takiego:

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(); 
} 
Powiązane problemy