2012-07-03 11 views
7

Tôi đang ở một con đường rất quan trọng trong phát triển ứng dụng di động đa nền tảng của mình ngay bây giờ và thực sự có thể sử dụng một số kiến ​​thức chuyên môn (như woah) .Xử lý lỗi .NET: thử/bắt VS sự kiện VS trả về giá trị/trạng thái trường

Để cung cấp cho một số ngữ cảnh (có thể giúp trả lời tôi hy vọng), tôi đang phát triển một ứng dụng trên thiết bị di động .NET dựa trên khung công tác MonoCross tiện dụng, sử dụng VS2010U (không phải MonoDevelop, đó là dành cho IOS) . Nền tảng nhắm mục tiêu đầu tiên là Android, sau đó lên các cổng "IOS và Windows Phone" (không thực sự nếu tôi làm đúng).

Bây giờ tôi đã có một nền tảng vững chắc, bao gồm logic nghiệp vụ, lớp truy cập dữ liệu, cơ sở dữ liệu, dịch vụ web REST, v.v. Tôi sẽ xem xét và cố gắng xử lý lỗi, nhưng tôi không chắc cách tiếp cận tốt nhất cho điều này là.

Tôi được thông báo rằng các khối try-catch có thể là các lần truy cập hiệu suất (đây là một vấn đề lớn trong trường hợp này), là
điều này có đúng không? Tôi có nên sử dụng chúng một cách tiết kiệm, hoặc chỉ tát em bất cứ nơi nào ngoại lệ có thể được ném (Tôi muốn sử dụng chúng xung quanh tất cả các cuộc gọi API SQLite của tôi, vì tôi không biết những gì heck họ đang làm một nửa thời gian) .

Đang sử dụng gọi lại sự kiện là điều xấu để xử lý lỗi? Tôi được khuyên nên sử dụng những thứ này bất cứ khi nào có thể, thay vì try-catch, vì lý do hiệu suất, nhưng tôi không muốn phá vỡ bất kỳ nguyên tắc và mô hình nào về thiết kế và kết thúc bằng mã sloppy-gauh-loppy trên khắp nơi.

Tùy chọn thứ ba, có số tiền chi phí thấp nhất, nhưng vô cùng khó chịu để xử lý với, là các trường trạng thái và giá trị trả lại.

Vì vậy, các bạn nghĩ sao? Tôi đoán tôi đang tìm kiếm một số hướng chung, và có lẽ một số gợi ý về nơi và khi nào sử dụng mỗi, và bất kỳ kỹ thuật khác tôi rất có thể bỏ ra. Xin vui lòng cho tôi biết nếu cần thêm chi tiết, vì tôi rất vui khi tặng em.

Cảm ơn bạn đã dành chút thời gian cho việc này!

+0

ngoại lệ bắt là chậm hơn các hình thức xử lý lỗi khác, điều đó đúng.Xử lý sự kiện phụ thuộc hoàn toàn vào cách xử lý sự kiện. Giá trị trả về sẽ ít tốn kém nhất. Rất có thể là bạn có thể sử dụng bất kỳ một trong số họ mà không có vấn đề, trừ khi bạn đang xử lý hàng ngàn cuộc gọi mỗi giây. – Wug

+0

Tôi chắc chắn sẽ ghi nhớ điều này. Rất tốt, cảm ơn! – samosaris

+0

Bài đăng tuyệt vời để xử lý ngoại lệ trong .NET: http://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET – samosaris

Trả lời

1

Thỉnh thoảng lý thuyết không phù hợp với triển khai cụ thể, nhưng tôi tưởng tượng Mono đã có những khái niệm này tại chỗ trong một thời gian.

Thời gian chạy thích hợp luôn ưu tiên hiệu suất trong trường hợp không có ngoại lệ. Lý tưởng nhất, trong trường hợp không có ngoại lệ được ném, khối try/catch sẽ thực hiện giống như nội dung của khối try được thực hiện trên chính nó, và khối try/finally sẽ thực thi như thể nội dung của try và cuối cùng là block được thực hiện theo thứ tự. Khi sử dụng một thông dịch viên bytecode CIL, thông thường không thể thực hiện các thao tác này mà không có phí như tôi đề cập ở đây. Tuy nhiên, một trình biên dịch JIT hoặc AOT phong nha (giống như bạn nhận được với Mono) thực tế tạo ra mã chạy nhanh như trong trường hợp ngoại lệ miễn là nó sẽ bị bỏ sót.¹

Nếu thay vào đó, bạn chọn chiến lược mã lỗi, ứng dụng của bạn sẽ kết thúc thực thi các phần của mã xử lý lỗi ngay cả khi không xảy ra lỗi (chuyển một tham số bổ sung cho các phương thức, tính toán và kiểm tra mã trả lại, v.v.). Do đó, mục tiêu của bạn là hạn chế việc sử dụng xử lý ngoại lệ đối với các trường hợp thực sự đặc biệt. Chiến lược này dẫn đến một ứng dụng mạnh mẽ (xử lý lỗi thích hợp) mà không làm giảm hiệu suất cho các trường hợp thành công quan trọng về hiệu năng.

¹ Điều này không chính xác 100% trong trường hợp khối thử/cuối cùng được nhúng vào phần thân của vòng lặp tính toán số, nhưng cơ hội có tác động hiệu suất quan sát được khi sử dụng đúng cách để xử lý các trường hợp ngoại lệ tại điểm này. Cụ thể, một khối try/finally JIT được biên dịch cho X86 sẽ bao gồm mã giống như một lệnh push/pop/jmp (nhánh nội bộ) so với cùng một phương thức mà không có khối try/finally. Đây là chi phí thấp hơn một cuộc gọi đến một phương thức được xác định là: public static void Foo() {}

+0

dooood ... làm thế nào bout họ táo! cảm ơn vì những viên đá quý này. hãy để tôi đoán, bạn cuộn datsun và một camero! – samosaris

+0

@SamusArin Datsun của tôi có động cơ từ Camaro: http://www.280z28.org/images/z/IMG_2020.jpg –

+0

gangsta chính thức! bạn rollin cứng trong đó với một chevy khối nhỏ v8! thật sự sử thi. – samosaris

1

Sử dụng try/catch khi bạn muốn để bắt ngoại lệ dự kiến ​​. Thông thường xác định worklfow bởi các ngoại lệ không phải là lựa chọn tốt, nhưng nó có thể là trường hợp duy nhất trong trường hợp hoạt động IO. Ví dụ bạn viết cho một số thiết bị bên ngoài mà đột nhiên bị mất kết nối. Trong trường hợp này, chương trình của bạn sẽ nhận được một ngoại lệ, nhưng phải xử lý nó như một lỗi thông thường.

+0

Tigran: để làm rõ, bạn sử dụng try/catch khi bạn DO mong đợi rằng một execption có thể xảy ra (như, khi bạn có một linh cảm cuộc gọi đôi khi có thể gây ra một vấn đề/execption)? Ngược lại, đừng bận tâm đến việc thử/bắt các cuộc gọi “bình thường” ok? – samosaris

+0

@SamusArin: chính xác. – Tigran

+0

Ok, cảm ơn, tôi nghĩ rằng tôi có thể xử lý điều đó (heh, không có ý định chơi chữ). – samosaris

4

Tôi nghĩ điều khiến chương trình của bạn xấu đi là xử lý ngoại lệ ở mọi nơi, mặc dù thực tế là chúng tôi có các mẫu xử lý ngoại lệ tốt tại chỗ.

Những loại chức năng đó sẽ xảy ra trên tất cả các bạn mã cơ sở được gọi là Hội Chữ thập lo ngại cắt như khai thác gỗ, an ninh, kiểm toán, xử lý ngoại lệ và ....

Bạn có thể tìm thấy các mẫu tốt ở đây http://msdn.microsoft.com/en-us/library/ee658105.aspx#ExceptionManagement.

Đáng nói đến là tôi không khuyên bạn nên sử dụng EntLib như được khuyến nghị trong tài liệu của Microsoft.

Nếu bạn tìm kiếm Lập trình hướng Aspect (AOP), bạn sẽ tìm thấy tài nguyên tốt. Và gợi ý cuối cùng là việc triển khai sẽ sử dụng Dependency Injection/IoC Framework để giải quyết những mối quan ngại này.

+1

hoàn toàn moley, đó là một bài báo thực sự tốt! cảm ơn Jani lần nữa, bạn tha người! – samosaris

+0

@SamusArin Tôi đã cam kết giúp bạn đêm qua :-) –

+0

+1 vì mã xử lý ngoại lệ là xấu xí và tẻ nhạt. – Wug

2

Tôi muốn sử dụng chúng xung quanh tất cả các cuộc gọi API SQLite của tôi, vì tôi không biết họ đang làm gì một nửa thời gian.

Nếu bạn nói rằng bạn đang sử dụng một thư viện cho interfacing với SQLite, rất có thể là thư viện này API đã được ném ngoại lệ về trường hợp lỗi nhất định. Tất nhiên, khi đây là trường hợp, bạn nên sử dụng try/catch xung quanh các cuộc gọi và xử lý các tình huống sai lầm.

Điều này luôn xảy ra khi bạn không tự viết mã đó, khi bạn đang sử dụng thư viện của người khác.

Cách bạn xử lý các lỗi này là quyết định của bạn.

Lời khuyên của tôi:

  • Tôi chống callbacks/sự kiện cho hầu hết các trường hợp. Những phần lớn này nên được sử dụng khi API dẫn đến lỗi là không đồng bộ và luồng chương trình đã không hiển nhiên vì điều đó.
  • Trường hợp ngoại lệ ném thực sự chậm hơn mã trạng thái/giá trị trả lại nhưng có thể được sử dụng an toàn trên bất kỳ nền tảng di động nào trong ngày hôm nay trong mọi trường hợp ứng dụng không quan trọng về thời gian. Trò chơi dành cho thiết bị di động sử dụng tính năng ném ngoại lệ và chúng là thời gian quan trọng (loại).
  • Ném ngoại lệ cung cấp khả năng đọc mã tốt hơn - theo ý kiến ​​của tôi, đó là một điều chủ quan - và là một cách hay để nhảy ra khỏi ngữ cảnh hiện tại trong trường hợp có lỗi.
+0

Có, tôi đang sử dụng API System.Data.SQLite, và có, một số phương pháp làm chúng ném (tôi vừa giải mã với dotPeek), vì vậy tôi sẽ thử/bắt tương ứng. Lời khuyên tuyệt vời, cảm ơn một tấn! – samosaris