2016-12-01 18 views
5

tôi có thể thay đổi vòng lặp của tôiThay đổi vòng lặp for để Parallel.For loop

for (int i = 0; i < something; i++) 

tới:

Parallel.For(0, something, i => 

Nhưng làm thế nào để làm điều này với vòng lặp này ?:

for (i = 3; i <= something/2; i = i + 2) 

Cảm ơn cho câu trả lời.

Trả lời

7

Kể từ

for (int i = 3; i <= something/2; i = i + 2) 
{ 
    ... 
} 

có thể được viết lại thành

for (int k = 1; k < (something + 2)/4; ++k) 
{ 
    int i = 1 + 2 * k; 
    ... 
} 

bạn có thể đặt

Parallel.For(1, (something + 2)/4, k => 
{ 
    int i = 1 + 2 * k; 
    ... 
}); 
3

Tham số thứ ba là delegate. Vì vậy, mỗi lần lặp lại bạn có thể chỉ định biến số lập chỉ mục của bạn sẽ làm gì bên trong ủy nhiệm.

EDIT: Ok tìm thấy một giải pháp làm việc: Như đã được đề xuất bởi Dmitry Bychenko bạn vẫn nên bắt đầu từ 0 và chỉ cần thêm startValue là giờ chênh lệch

int something = 16; 

int startValue = 3; 
int stepSize = 2; 

List<int> numbers = Enumerable.Range(0, 20).ToList(); 

Parallel.For(0, something/2, i => 
{ 
    int ind = (stepSize * i) + startValue ; Console.WriteLine(numbers[ind]); 
}); 
+1

Điều này không làm những gì anh ta hỏi. mã của bạn chạy cho các giá trị 5, 6, 7, 8, 9 song song, trong khi anh ta muốn nó tương đương với vòng lặp bỏ qua mọi mục thứ hai (giá trị: 3, 5, 7). –

+0

Lưu ý rằng việc thay đổi 'i' bên trong' delegate' không thay đổi số 'Parallel.For' và nó chỉ là một kiểu giá trị được sao chép -' int'. –

+0

Tôi thấy điều đó! bạn hoàn toàn đúng. –

1

Dmitry câu trả lời Bychenko 's nhận được nó nhưng bạn cũng có thể thực hiện riêng bạn ParallelFor với bước tùy chỉnh mà sẽ làm cho mã của bạn một chút dễ đọc hơn:

static void ParallelFor(int start, int last, Func<int, int> step, Action<int> action) 
{ 
    var enumerable = StepEnumerable<int> 
     .Create(start, step) 
     .TakeWhile(x => x < last); 

    Parallel.ForEach(enumerable, action); 
} 

Đây là Triển khai của StepEnumerable:

public class StepEnumerator<T> : IEnumerator<T> 
{ 
    ... 

    public StepEnumerable(T value, Func<T, T> manipulation) 
    { 
     mEnumerator = new StepEnumerator<T>(value, manipulation); 
    } 

    public static StepEnumerable<T> Create(T value, Func<T, T> manipulation) 
    { 
     return new StepEnumerable<T>(value, manipulation); 
    } 

    ... 
} 

public class StepEnumerator<T> : IEnumerator<T> 
{ 
    public bool MoveNext() 
    { 
     Current = mManipulation(Current); 
     return true; 
    } 
} 

Sau đó, ví dụ: bạn chạy đoạn mã sau:

ParallelFor(3, 16, x => x + 2, Console.WriteLine); 

Bạn sẽ nhận được đầu ra sau (Trong dòng riêng biệt tất nhiên):

5, 11, 7, 13, 9, 15