2012-01-16 33 views
7

Tôi muốn đảm bảo rằng ứng dụng web của tôi hoạt động hiệu quả và sẽ không gây ra bất kỳ vấn đề hiệu suất nào. Khi tôi tìm kiếm, tôi thấy rằng một trong những vấn đề phổ biến nhất liên quan đến vấn đề hiệu suất là vấn đề "vòng lặp vô hạn".Làm cách nào để phát hiện và tránh các vòng lặp vô hạn?

Tôi muốn hỏi:

Tôi nên bắt đầu kiểm tra xem mã của mình không bao giờ gây ra vòng lặp vô hạn?

Có bài viết, lời khuyên, chỉ dẫn, ví dụ nào không? Tôi sẽ biết ơn.

ví dụ:

Có thể mã này gây ra vòng lặp vô hạn?

public static IEnumerable<SubjectNode> ReadSubjectNodes(string filePath) 
{ 
    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) 
    using (XmlReader xrdr = new XmlTextReader(fs)) 
     while (xrdr.Read()) 
      if (xrdr.NodeType == XmlNodeType.Element && xrdr.LocalName == "subject") 
       yield return new SubjectNode(xrdr.GetAttribute("id"), xrdr.GetAttribute("name"), xrdr.GetAttribute("short")); 
} 

Cảm ơn trước

+1

Có thể đặt một số giới hạn trên lớn, tức là 'int ReadCount = 100000; while (xrdr.Read() && ReadCount--> 0) ' –

+6

Điều này rất có thể không phải là những gì bạn đang tìm kiếm, nhưng vấn đề chung là tìm hiểu xem một chương trình có tham gia vòng lặp vô hạn hay kết thúc hay không ([" tạm dừng sự cố " ] (http://en.wikipedia.org/wiki/Halting_problem)) là không thể giải quyết được. – svick

+0

Mã chính xác là gì? Bạn sẽ xuất kết quả này cho người dùng hay đây có phải là thực thi đằng sau hậu trường không?Nếu bạn xuất kết quả cho người dùng, bạn có thể nhận được 10 -> hiển thị kết quả đầu tiên -> sau đó chuyển hướng từ trang này sang trang khác mỗi lần chỉ lặp lại 10 tệp tiếp theo. –

Trả lời

5

Vâng, AFAIK rằng mã sẽ không nguyên nhân một vòng lặp vô hạn - nó không phải là đệ quy, và một XmlReader từ các tập tin hệ thống cuối cùng sẽ chạy ra khỏi dữ liệu. Tuy nhiên, có thể là chạy dài. Trong một số trường hợp, việc thêm kiểm tra tính chính xác có thể hữu ích - đây có thể là bộ đếm hoặc kiểm tra ngược thời gian. Ví dụ:

public static IEnumerable<SubjectNode> ReadSubjectNodes(string filePath) 
{ 
    int safetyCheck = 10000; 
    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) 
    using (XmlReader xrdr = new XmlTextReader(fs)) 
     while (xrdr.Read()) { 
      if(--safetyCheck == 0) throw new SomeTypeOfException(); 
      ... more code 
     } 
    ... more code 
} 
+0

Cảm ơn rất nhiều. Nhưng có lời khuyên chung nào tôi nên quan tâm không? –

2

Mã bạn đã đăng ở đây có điều kiện thoát: Khi XmlTextReader kết thúc luồng của nó. Vì vậy, nó không phải là một vòng lặp vô hạn.

Đó thực sự là những gì bạn cần làm để ngăn chặn những điều này: đảm bảo mọi vòng lặp có điều kiện sẽ khiến nó thoát. Việc viết mã dễ dàng hơn nhiều so với việc xem lại sau.

2

Không có cách nào để xác định trước liệu vòng lặp có chạy vô hạn hay không, ngoại trừ vòng lặp có số lần lặp được xác định và không thay đổi bộ đếm lặp trong cơ thể.

Chỉ cần viết mã tốt mà không phải là dễ bị vòng lặp vô hạn: kiểm tra các điều kiện bên trong vòng thời gian và suy nghĩ về một trường hợp trong đó họ sức nguyên nhân vô hạn lặp lại. Đó là nó.

1

Vòng infinate xảy ra khi bạn đang lặp cho đến khi tham số được đáp ứng (vòng lặp while), nhưng có thể mệnh đề while không bao giờ thỏa mãn để thoát khỏi vòng lặp. Và do đó nó cứ mãi mãi. Nó cũng có thể gây ra một vòng lặp đệ quy, bởi nơi bạn gọi một hàm từ bên trong chính nó (hoặc tương tự), nơi nó sẽ liên tục gọi lên một hàm, nhưng không bao giờ đến gần hơn để thoát ra ngoài.

while (xrdr.Read()), miễn là .Read() đang gọi tự động chuyển đến phần tử tiếp theo. Tại đó, vì xrdr của bạn không phải là một nguồn vô hạn, nó cuối cùng sẽ đạt được kết thúc và thoát.

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