2013-04-28 33 views
7

Tôi gặp khó khăn khi hiểu số loopState.Stop()loopState.Break(). Tôi đã đọc MSDN và một số bài viết về nó nhưng tôi vẫn còn bối rối.Dừng và ngắt trong Parallel.For

Điều tôi hiểu là mỗi trình phân vùng lặp lại cung cấp các chỉ mục còn lại cho các luồng để xử lý và loopState.Stop() dừng tất cả luồng và loopState.Break() dừng luồng hiện tại.

Tuy nhiên cho phép xem xét sau tình huống:

Parallel.For(0, 100, (i, loopState) => 
{ 
    if (i >= 10) 
     loopState.Break(); 
    Debug.Write(i); 
}); 

cho vòng lặp này, tôi có kết quả fallowing:

0 25 1 2 3 4 5 6 7 8 9 10 

Tôi không có ý tưởng tại sao trong kết quả có 10 và 25 số.

Mọi người đều có thể trợ giúp?

P.S. Tôi có CPU i5 520M (2 lõi => 4 Chủ đề)

Trả lời

9

loopState.Break() không phá vỡ chức năng như return. Vì vậy, dòng sau loopState.Break() sẽ vẫn được thực hiện. Sau khi phạm vi đó đã kết thúc cho số đó, for kiểm tra xem số loopState.Break() đã được gọi hay chưa. Nếu vậy, tất cả các vòng được phép tiếp tục cho đến khi đạt được số đó gọi là Break.

Trong ví dụ của bạn, các vòng lặp từ 0 đến 24 sẽ ngắt cùng lúc với vòng lặp 25 đến 49 (và hiển thị số "bẻ gãy") của chúng.

Vòng 50..74 và 75..99 thậm chí sẽ không bắt đầu vì vòng lặp thứ hai 25..49 đã hủy bỏ toàn bộ hoạt động, vì số lượng của chúng lớn hơn số lượng vi phạm 10.

+0

Vì vậy, loopState.Break() thoát khỏi tất cả các chủ đề? Tôi sử dụng để điều đó loopState.Stop() hiện nó. –

+0

Để làm rõ bình luận trước đây của tôi: Tôi hiểu bây giờ làm thế nào hai vòng đầu tiên dừng lại nhưng tại sao hai chủ đề khác thậm chí không bắt đầu? Là Break có thể chấm dứt nhiều hơn sau đó một sợi? Nếu vậy nó như thế nào? –

+0

Xem câu trả lời hay về Stop vs Break: http://stackoverflow.com/questions/8818203/what-is-difference-between-loopstate-break-loopstate-stop-and-cancellationt –

3

Từ the documentation of Break():

nghỉ giải lao có thể được sử dụng để giao tiếp với các vòng lặp mà không lặp khác sau khi lặp hiện tại cần được chạy. Ví dụ, nếu Break được gọi từ vòng lặp thứ 100 của vòng lặp for lặp lại song song từ 0 đến 1000, tất cả các lần lặp lại nhỏ hơn 100 vẫn nên được chạy, nhưng các lần lặp từ 101 đến 1000 là không cần thiết.

Điều này có nghĩa là lặp lại hiện tại sẽ vẫn kết thúc (vì vậy, 10 được in). Break() cũng không có khả năng đi lại thời gian, do đó, 25 sẽ vẫn được in. Ý nghĩa của số Break() là không mới lặp lại vượt quá 10 sẽ được bắt đầu.

0

Break đảm bảo rằng tất cả các lần lặp hiện đang chạy sẽ được hoàn tất.

Dừng vừa chấm dứt mọi thứ.

1

if (i >= 10) loopState.Break(); sẽ vẫn tiếp tục lặp lại hiện tại. Vì vậy, 10 được in.

Tuy nhiên, lặp lại (i> = 10) sau khi gọi loopState.Break() sẽ không bắt đầu.

Nhưng tại sao 25 được in? Hình ảnh sau sẽ giải thích lý do. Vì bạn có 4 chuỗi, 0-99 sẽ được chia thành 4.

Chủ đề thứ nhất có: 0-24.
chủ đề thứ 2 có: 25 - 49.
chủ đề thứ 3 có: 50 - 74.
chủ đề thứ 4 có: 75 - 99.

Dựa trên sự hiểu biết của tôi, mỗi thread sẽ lặp con số của chính nó. Theo số this post, nó cho biết

Lặp lại bổ sung có thể được chạy, nếu chúng đã bắt đầu khi Break được gọi.

Khi chuỗi thứ hai đã bắt đầu gần như cùng thời điểm với chuỗi thứ nhất, vì vậy, 0, 25 được in. Sau đó, if (i >= 10) loopState.Break(); được gọi khi vòng lặp 25 trong chuỗi thứ hai.

Các vòng trong chuỗi thứ 3 và thứ 4 không bắt đầu trước khi Break() được gọi là do đó bất kỳ số nào lớn hơn 10 không in.

ảnh ref: http://www.albahari.com/threading/part5.aspx

0

Tất cả các phương pháp từ tĩnh Parallel lớp trả ParallelLoopResult .Đây đối tượng có hai thuộc tính - IsCompletedLowestBreakIteration

Khi chúng tôi sử dụng loopState.Break(), LowestBreakIteration trả về một số nguyên đại diện cho lặp thấp nhất từ đó tuyên bố Break được gọi là

Khi chúng tôi sử dụng loopState.Stop(), LowestBreakIteration Trả về null

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