引发错误,释放对象并重新创建它

本文关键字:新创建 创建 错误 释放 对象 | 更新日期: 2023-09-27 18:36:53

假设我们有以下两个类,我们如何侦听错误,如果发生任何错误,请重新创建单例?我已经整理了以下代码,但想知道是否有一种模式可以安全地引发错误、释放对象并自动重新创建它?

'

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

    }
}

'

引发错误,释放对象并重新创建它

如果我理解得很好,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();
    }
}

注意:释放服务会使对象失效,并使客户端对其的任何引用无效。但是重新创建一个新的不会给客户一个新的参考!您需要具有对客户端引用的引用,以便能够为客户端提供新实例。