2016-04-28 19 views
5

Tôi đã phương pháp sauCách xử lý luồng bộ nhớ trong tác vụ?

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

Làm thế nào để xử lý một cách chính xác memoryStream rằng trong Task? Tôi cần phải xử lý đối tượng memoryStream khi tác vụ hoàn tất.

+3

Bạn không cần vứt bỏ MemoryStream nhưng câu hỏi vẫn hợp lệ. Nó có thể tốt cho chất lượng mã để đưa nó vào 'sử dụng'. – usr

+0

Làm thế nào tôi có thể đặt nó vào một 'sử dụng'? Tôi cần phải làm 'Task.WaitAll (tasks.ToArray());' sau một vòng lặp – Anatoly

+0

Thêm 'using' vào mã của một trong các câu trả lời. Họ nên đã sử dụng nó ở nơi đầu tiên nhưng có lẽ họ chỉ không bận tâm. – usr

Trả lời

2

Spl nó ra cơ thể while vòng lặp của bạn thành một phương pháp riêng biệt async:

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

Sau đó, sử dụng phương pháp mới của bạn:

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

Trên một mặt lưu ý, ngăn chặn trên mã không đồng bộ (Task.WaitAll) không phải là nói chung là một ý tưởng tốt . Một cách tiếp cận tự nhiên hơn là giữ cho nó không đồng bộ:

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

Vâng, đây là cách sạch nhất. Không có lý do gì để làm bất cứ điều gì khác. – usr

+0

Khi chúng tôi vứt bỏ một luồng? – Anatoly

+0

@Anatoly: Luồng được xử lý ở cuối khối 'using'. –

3

Bạn có hai lựa chọn:

1-đóng gói tất cả các quá trình bên trong một nhiệm vụ:

while(...) { 

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

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

    }); 

    tasks.Add(task); 
}  

2-Sử dụng một Tiếp tục:

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

    tasks.Add(task); 
}  
+0

Vâng, có rất nhiều cách để thực hiện việc này (ví dụ: có một Danh sách bên ngoài nơi bạn giữ các strerams và xử lý chúng sau WaitAll), nhưng hai cách này là cách sử dụng khung công tác Async. – Gusman

+0

Tôi cần phải vứt bỏ đối tượng 'memoryStream' khi công việc kết thúc. Tôi không muốn có từ khóa 'async/await'. Làm thế nào để thêm tiếp tục và xử lý dòng bên trong nó? – Anatoly

+0

sử dụng mã thứ hai ... đó là những gì nó làm. – Gusman

0

tôi sẽ làm một cái gì đó như thế này:

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(); 
} 
Các vấn đề liên quan