2016-10-17 16 views
6

là có cách nào cho Tìm kiếm không đồng bộ trong C#? nơi id (s) sẽ được xử lý không đồng bộ bằng phương pháp này, thay vì sử dụng Parallel.ForEachTìm kiếm không đồng bộ

//This Gets all the ID(s)-IEnumerable <int> 
var clientIds = new Clients().GetAllClientIds(); 

Parallel.ForEach(clientIds, ProcessId); //runs the method in parallel 

static void ProcessId(int id) 
{ 
// just process the id 
} 

nên một cái gì đó một foreach nhưng chạy không đồng bộ

foreach(var id in clientIds) 
{ 
    ProcessId(id) //runs the method with each Id asynchronously?? 
} 

tôi đang cố gắng để chạy Chương trình trong Bảng điều khiển, nó sẽ đợi tất cả (các) id xử lý xong trước khi đóng Console.

+0

Không chắc chắn những gì bạn đang yêu cầu ở đây. Tôi nghĩ rằng bạn đang yêu cầu một foreach đa luồng nhưng bạn không muốn sử dụng 'Parallel.ForEach' (đó là đa luồng)? – Igor

+0

Vâng, hàm 'ProcessId' của bạn có đồng bộ trong ví dụ thứ 2 không? nó trả về một 'Task'? Bạn không thể chỉ "làm cho một hàm asyncronous" bạn phải viết nó asyncronously hoặc thực hiện nó trên một thread (như 'Parallel.ForEach' hiện) –

+4

@Igor' Parallel.ForEach' không phải là không đồng bộ, nó đồng bộ xử lý các tác vụ song song . Ngoài ra nó không hỗ trợ async/await, vì vậy hãy cẩn thận trộn hai. –

Trả lời

12

Không, nó không thực sự khả thi.

Thay vì trong vòng lặp foreach, hãy thêm những gì bạn muốn làm làm nhiệm vụ Task for Task và sau đó sử dụng Task.WaitAll.

var tasks = new List<Task>(); 

foreach(var something in somethings) 
tasks.Add(DoJobAsync(something)); 

await Task.WhenAll(tasks); 

Lưu ý rằng phương pháp DoJobAsync sẽ trả về Tác vụ.

Cập nhật:

Nếu phương pháp của bạn không trả lại công tác nhưng cái gì khác (ví dụ như khoảng trống), bạn có hai lựa chọn đó là về cơ bản giống nhau:

1.Add Task.Run (hành động) để nhiệm vụ thu thập thay

tasks.Add(Task.Run(() => DoJob(something))); 

2.Wrap phương pháp đồng bộ hóa trong phương pháp trở về công tác

private Task DoJobAsync(Something something) 
{ 
    return Task.Run(() => DoJob(something)); 
} 

Bạn cũng có thể sử dụng Task<TResult> chung nếu bạn muốn nhận một số kết quả từ việc thực hiện tác vụ.

+0

Điều này có thực sự chạy nó không đồng bộ không? Tôi đang cố gắng để nhân rộng nó trên mã của tôi được nêu ra, có vẻ như tất cả các trường hợp DoJobAsync của tôi chạy một sau khi khác. – Anzurio

6

phương pháp mục tiêu của bạn sẽ phải trả lại một tác

static Task ProcessId(int id) 
{ 
    // just process the id 
} 

id Chế biến sẽ được thực hiện như thế này

// This Gets all the ID(s)-IEnumerable <int> 
var clientIds = new Clients().GetAllClientIds(); 
// This gets all the tasks to be executed 
var tasks = clientIds.Select(id => ProcessId(id)). 
// this will create a task that will complete when all of the `Task` 
// objects in an enumerable collection have completed. 
await Task.WhenAll(tasks); 
+0

Tôi đã nhanh hơn: P –

+1

@PawelTroka nhưng Nkosi sử dụng dễ dàng hơn '.Select (id => ProcessId (is))': P –

+0

Vâng, tôi vẫn còn khá mới trong cuộc đua đại diện này. –

Các vấn đề liên quan