2009-07-16 24 views
7

Tôi muốn biết liệu ngoại lệ unhandled sẽ làm cho vụ tai nạn dịch vụ WCF. Tôi đã viết chương trình sau đây cho thấy ngoại lệ unhandled trong một chủ đề bắt đầu bởi dịch vụ WCF sẽ làm cho toàn bộ vụ tai nạn WCF.ngoại lệ không được giải quyết sẽ khiến dịch vụ WCF bị lỗi?

Câu hỏi của tôi là, tôi muốn xác nhận xem có ngoại lệ không được đề cập trong các chủ đề (bắt đầu bằng dịch vụ WCF) sẽ khiến WCF gặp sự cố không? Sự nhầm lẫn của tôi là tôi nghĩ WCF nên được ổn định dịch vụ mà không nên sụp đổ vì ngoại lệ unhandled.

Tôi đang sử dụng VSTS 2008 + C# + .Net 3.5 để phát triển dịch vụ WCF dựa trên dịch vụ Windows tự lưu trữ.

Sau đây là các bộ phận liên quan của mã,

namespace Foo 
{ 
    // NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in Web.config. 
    [ServiceContract] 
    public interface IFoo 
    { 
     [OperationContract] 
     string Submit(string request); 
    } 
} 

namespace Foo 
{ 
    // NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file. 
    public class FooImpl : IFoo 
    { 
     public string Submit(string request) 
     { 
      return String.Empty; 
     } 
    } 
} 

namespace Foo 
{ 
    public partial class Service1 : ServiceBase 
    { 
     public Service1() 
     { 
      InitializeComponent(); 
     } 

     ServiceHost host = new ServiceHost(typeof(FooImpl)); 

     protected override void OnStart(string[] args) 
     { 
      host.Open(); 
      // start a thread which will throw unhandled exception 
      Thread t = new Thread(Workerjob); 
      t.Start(); 
     } 

     protected override void OnStop() 
     { 
      host.Close(); 
     } 

     public static void Workerjob() 
     { 
      Thread.Sleep(5000); 
      throw new Exception("unhandled"); 
     } 
    } 
} 
+2

Ví dụ của bạn không hiển thị "ngoại lệ unhandled trong một chủ đề bắt đầu bởi dịch vụ WCF" nhưng "ngoại lệ unhandled trong một chủ đề bắt đầu bởi dịch vụ Windows". Nó không liên quan gì đến WCF. –

+0

Tôi bắt đầu WCF tự lưu trữ trong Windows Service (host.Open()), mà tôi có nghĩa là unhandled ngoại lệ trong dịch vụ WCF. Xin lỗi vì cụm từ khó hiểu và bất kỳ nhận xét hoặc câu trả lời nào cho câu hỏi của tôi? – George2

Trả lời

11

Vâng, một ngoại lệ unhandled trong một thread sẽ mất quá trình này xuống.

Quá trình này sẽ sụp đổ:

static void Main(string[] args) 
{ 
    Thread t = new Thread(() => 
    { 
     throw new NullReferenceException(); 
    }); 
    t.Start(); 
    Console.ReadKey(); 
} 

Cái này sẽ không:

static void Main(string[] args) 
{ 
    Thread t = new Thread(() => 
    { 
     try 
     { 
      throw new NullReferenceException(); 
     } 
     catch (Exception exception) 
     { 
      Console.WriteLine(exception.ToString()); 
     } 
    }); 
    t.Start(); 
    Console.ReadKey(); 
} 
+0

Cảm ơn, rất vui khi biết điều đó. – George2

3

Nếu bạn không xử lý một ngoại lệ đó được thông qua trên hệ điều hành và nó sẽ trả lời bằng cách giết chết những gì bao giờ ứng dụng gây ra ngoại lệ.

Tại sao bạn không thêm try/catch để xử lý các ngoại lệ để dịch vụ của bạn không bị giết?

+0

Không nếu ngoại lệ xảy ra trong một chủ đề khác với chủ đề chính. Xem ví dụ của Fredrik Mörk ở trên. – user141682

+0

Trong ví dụ của Fredrik có một khối try/catch để ngăn chặn ngoại lệ từ việc gỡ bỏ quá trình, đó là chính xác những gì tôi đã nói ở trên. – jussij

1

Nếu bạn không xử lý lỗi đúng cách, chương trình sẽ làm cho chương trình gặp sự cố. Thực hành tốt của nó để đặt một số

try{//do something 
} 
catch{ //handle errors 
} 
finally{//final clean up 
} 

chặn mã ngoại lệ để xử lý nó một cách duyên dáng. các ví dụ tại http://msdn.microsoft.com/en-us/library/fk6t46tz(VS.71).aspx

17

Ngoại lệ không được xử lý ở phía dịch vụ sẽ khiến kênh (kết nối giữa máy khách và máy chủ) bị lỗi "- ví dụ: bị rách nát.

Từ thời điểm đó trở đi, bạn không thể gọi từ máy khách bằng cùng một đối tượng ứng dụng khách proxy nữa - bạn sẽ phải tạo lại ứng dụng khách proxy.

Đặt cược tốt nhất của bạn là xử lý tất cả các lỗi ở phía máy chủ bất cứ khi nào có thể. Kiểm tra giao diện IErrorHandler mà bạn nên triển khai trên lớp triển khai dịch vụ của mình để tắt tất cả ngoại lệ .NET thành lỗi SOAP (sẽ NOT khiến kênh bị lỗi) hoặc báo cáo/nuốt chúng hoàn toàn.

Marc

+0

Xin chào Marc, tôi đã đọc kỹ liên kết MSDN được đề xuất của bạn về IErrorHandler một cách cẩn thận. Một sự nhầm lẫn, ngoại lệ unhandled của vấn đề của tôi là từ một thread được bắt đầu bởi bản thân mình explciitly, và nó không phải là một thread hoạt động WCF. Tôi nghĩ rằng IErrorHandler bắt ngoại lệ unhandled trong thread hoạt động WCF (tức là thread mà thực hiện OperationContract hoạt động), và kể từ thread của tôi không phải là thread hoạt động WCF, nó không liên quan đến vấn đề của tôi, chính xác? Có ý kiến ​​gì không? – George2

+1

bạn có bắt đầu chuỗi đó từ mã máy chủ WCF của bạn không? Câu hỏi thực sự là: sẽ làm hỏng chuỗi của bạn ảnh hưởng đến mã máy chủ của bạn - nếu nó dẫn đến một ngoại lệ trong mã máy chủ của bạn, thì việc triển khai giao diện IErrorHandler sẽ giúp ích. –

+0

Cảm ơn Marc, 1. Tôi đang bối rối về những gì có nghĩa là "bắt đầu thread đó từ mã máy chủ WCF của bạn", bạn có thể làm rõ xin vui lòng? WCF từ điểm phát triển của xem chỉ là một tập hợp các hợp đồng, tôi không chắc chắn những gì bạn có nghĩa là máy chủ WCF. :-) 2. Bạn có nghĩa là ngoại lệ unhandled từ thread không WCF cũng sẽ bị bắt bởi IErrorHandler? – George2

7

Hành vi mặc định của thời gian chạy WCF là nuốt tất cả ngoại trừ một vài loại ngoại lệ. Vì vậy, nếu mã của bạn ném một ngoại lệ xuống ngăn xếp đến thời gian chạy WCF (chẳng hạn như nếu bạn ném từ một hoạt động WCF), nó sẽ không sụp đổ ứng dụng (trừ khi nó được coi là một ngoại lệ "chết người", chẳng hạn như OOM, SEHException, vv .). Nếu ngoại lệ không phải là một phần của hợp đồng lỗi của hoạt động, thì kênh sẽ bị lỗi, nếu không thì không.

Nếu thời gian chạy WCF không nằm trong mã của bạn trên ngăn xếp, thì trường hợp ngoại lệ/sẽ/hỏng quy trình.

Điều này tương tự như thời gian chạy ASP.NET.

Nếu bạn muốn sàng lọc ngoại lệ bay ra khỏi các hoạt động WCF theo cách tổng quát, tôi khuyên bạn nên sử dụng giao diện IOperationInvoker. Bạn cũng có thể sử dụng IErrorHandler, nhưng việc triển khai IErrorHandler của bạn sẽ được thông báo về các ngoại lệ khác với các mã được ném từ "mã người dùng" (các hoạt động WCF), chẳng hạn như SocketAbortedExceptions trên các chủ đề I/O nội bộ WCF, có lẽ không thú vị với bạn.

1

Bạn có thể sử dụng FaultException để truyền đạt lỗi cho phía máy khách và giữ logic trong dịch vụ.

Kiểm tra điều này example, hy vọng nó sẽ giúp bạn.

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