2016-04-28 9 views
5

Ho il seguente metodoCome smaltire il flusso di memoria che nell'attività?

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

Come smaltire correttamente memoryStream che nel Task? Devo eliminare l'oggetto memoryStream quando l'attività è terminata.

+3

Non è necessario disporre di MemoryStream ma la domanda è ancora valida. Può essere buono per la qualità del codice metterlo in "uso". – usr

+0

Come posso metterlo in un 'uso'? Ho bisogno di fare 'Task.WaitAll (tasks.ToArray());' dopo un ciclo – Anatoly

+0

Aggiungi 'using' al codice di una delle risposte. Avrebbero dovuto usarlo in primo luogo, ma forse non si sono preoccupati. – usr

risposta

2

Spl fuori il corpo while anello in un metodo separato async:

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

quindi utilizzare il nuovo metodo:

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

Su un lato nota, bloccando il codice asincrono (Task.WaitAll) non è generalmente una buona idea . Un approccio più naturale è di mantenerlo asincrono:

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

Sì, questo è il modo più pulito. Non c'è motivo di fare altro. – usr

+0

Quando disponiamo un flusso? – Anatoly

+0

@Anatoly: lo stream è disposto alla fine del blocco 'using'. –

3

si hanno due opzioni:

1-incapsulare tutto il processo all'interno di un compito:

while(...) { 

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

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

    }); 

    tasks.Add(task); 
}  

2-Utilizzare una continuazione:

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

    tasks.Add(task); 
}  
+0

Bene, ci sono molti altri modi per farlo (per esempio avere un elenco esterno dove si tengono le strerams e le si dispongono dopo l'WaitAll), ma questi due modi sono quelli che usano il framework Async. – Gusman

+0

Ho bisogno di gettare l'oggetto 'memoryStream' quando l'attività è terminata. Non voglio avere parole chiave 'async/await'. Come aggiungere continuazione e smaltire il flusso al suo interno? – Anatoly

+0

usa il secondo codice ... è quello che fa. – Gusman

0

vorrei fare qualcosa di simile:

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