簡體   English   中英

未處理的異常會使WCF服務崩潰嗎?

[英]unhandled exception will make WCF service crash?

我想知道未處理的異常是否會使WCF服務崩潰。 我編寫了以下程序,該程序顯示WCF服務啟動的線程中未處理的異常將使整個WCF服務崩潰。

我的問題是,我想確認線程中未處理的異常(由WCF服務啟動)是否會使WCF崩潰? 我的困惑是,我認為WCF應該是穩定的服務,不應因未處理的異常而崩潰。

我正在使用VSTS 2008 + C#+ .Net 3.5開發基於WCF服務的自托管Windows服務。

這是代碼的相關部分,

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");
        }
    }
}

服務端未處理的異常將導致通道(客戶端和服務器之間的連接)“發生故障”,例如被拆除。

從那時起,您將無法再使用相同的代理客戶端對象實例從客戶端進行調用-您將不得不重新創建代理客戶端。

最好的選擇是盡可能處理服務器端的所有錯誤。 檢出應該在服務實現類上實現的IErrorHandler接口,以將所有未處理的.NET異常轉換為SOAP錯誤( 不會導致通道故障),或者完全報告/吞噬它們。

是的,線程中未處理的異常會導致進程中斷。

此過程將崩潰:

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

這將不會:

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

WCF運行時的默認行為是吞入除少數幾種類型之外的所有異常。 因此,如果您的代碼向WCF運行時拋出了異常(例如,從WCF操作中拋出),則它不會使應用程序崩潰(除非它被視為“致命”異常,例如OOM,SEHException等) )。 如果異常不是操作故障合同的一部分,則通道將發生故障,否則就不會發生故障。

如果WCF運行時不在堆棧上的代碼下,則異常/ will /將使進程崩潰。

這類似於ASP.NET運行時。

如果您希望以一般方式篩選出WCF操作中溢出的異常,建議使用IOperationInvoker界面。 您也可以使用IErrorHandler,但是將向IErrorHandler實現通知除“用戶代碼”(WCF操作)引發的異常以外的其他異常,例如WCF內部I / O線程上的SocketAbortedException,這些異常可能對您而言並不有趣。

如果您不處理異常,它將在操作系統上傳遞,並且它將通過殺死導致該異常的應用程序做出響應。

您為什么不只添加try / catch來處理異常,以使服務不會被殺死?

如果沒有適當的錯誤處理,它將使程序崩潰。 好的做法是

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

在您的代碼中進行阻止,以確保是否確實引發了異常。 http://msdn.microsoft.com/zh-cn/library/fk6t46tz(VS.71).aspx上的示例

您可以使用FaultException將錯誤傳達給客戶端,並將邏輯保留在服務中。

檢查此示例 ,希望對您有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM