2016-03-01 21 views
0

假設我們有以下兩個類,我們如何監聽錯誤,如果發生錯誤,重新創建單例?我已經將以下代碼放在一起,但想知道是否有安全引發錯誤的模式,處理對象並自動重新創建它?引發錯誤,處置對象並重新創建它

`

static void Main(string[] args) 
    { 
     MyFirstClass.Instance.SayHello(); 
    } 
} 
class MySecondClass 
{ 
    public int ID { get; set; } 
    public void SayHelloFromSecondClass() 
    { 
     Console.WriteLine("Say Hello From Second Class"); 
    } 
    public MySecondClass(int id) 
    { 
     ID = id; 
    } 
} 

public sealed class MyFirstClass 
{ 
    private static readonly MyFirstClass instance = new MyFirstClass(); 
    private static MySecondClass msc; 

    public event EventHandler ErrorOccuredEvent; 

    private MyFirstClass() { } 

    public static MyFirstClass Instance 
    { 
     get 
     { 
      msc = new MySecondClass(id: 1); 
      return instance; 
     } 
    } 

    public void SayHello() 
    { 
     Console.WriteLine("Hello World..."); 

    } 

    static void ErrorOccured(object sender, EventArgs e) 
    { 
     Console.WriteLine("Oops"); 
     msc = null; 
     Thread.Sleep(5000); 
     GC.Collect(); 
     msc = new MySecondClass(id: 2); 


    } 
} 

`

+0

'msc'與'instance'的關係如何?這樣的代碼似乎沒有多大意義。你能更具體地說明你想要做什麼嗎?你真正的目標是什麼? –

+0

@ OlivierJacot-Descombes謝謝,我有兩個目標:1)我希望'EntryClass'是一個單獨的,只創建一個單獨的'ServiceClass'實例,現在這裏的問題是是否刪除' EntryClass'並使'ServiceClass'成爲一個Singleton本身? 2)我想讓「EntryClass」監聽錯誤,如果發生錯誤,自動處理ServiceClass並重新創建它。 –

回答

2

如果我沒理解好,MyFirstClass(這是一個單)是一種包裝的,輪流MySecondClass到一個單左右MySecondClass爲好。

我們叫MyFirstClassWrapper

讓我們呼籲MySecondClassService

如果客戶機總是通過Wrapper的單個實例消耗Service,然後重新創建一個Wrapper也無濟於事,因爲客戶端可能保留對Wapper的引用。如果客戶沒有看到它並且不能保留對其的引用,則重新創建Service可以提供幫助。因此他們必須間接地使用服務。

這是最簡單的通過一個接口來實現這一目標:

public interface IHelloService 
{ 
    void SayHello(); 
} 

public class HelloService : IHelloService 
{ 
    public void SayHello() 
    { 
     Console.WriteLine("Hello"); 
    } 
} 

public class HelloServiceWrapper : IHelloService 
{ 
    public static readonly IHelloService Instance = new HelloServiceWrapper(); 

    private HelloServiceWrapper() {} 

    private IHelloService _service; 

    public void SayHello() 
    { 
     EnsureServiceAvailable(); 
     _service.SayHello(); 
    } 

    private void EnsureServiceAvailable() 
    { 
     if(_service == null) { 
      _service = new HelloService(); 
     } 
    } 

    private void HandleError() 
    { 
     _service = null; 
    } 
} 

但是,如果當客戶端使用該服務中出現錯誤...

HelloServiceWrapper.Instace.SayHello(); 

...此調用可能會失敗。

你將不得不爲了使成功的客戶端調用(假設重新創建該服務將解決這個問題,並不會立即再次出現錯誤)立即重新創建服務:

public void SayHello() 
{ 
    try { 
     _service.SayHello(); 
    } catch { 
     _service = new HelloService(); 
     _service.SayHello(); 
    } 
} 

注意:處理服務使對象無效,並使客戶端對它的引用無效。但重新創建一個新的不會給客戶一個新的參考!您需要參考客戶端引用以便能夠爲客戶端提供一個新實例。