引发错误,释放对象并重新创建它
本文关键字:新创建 创建 错误 释放 对象 | 更新日期: 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
变成单例。
让我们称MyFirstClass
:Wrapper
让我们称MySecondClass
:Service
如果客户端始终通过 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();
}
}
注意:释放服务会使对象失效,并使客户端对其的任何引用无效。但是重新创建一个新的不会给客户一个新的参考!您需要具有对客户端引用的引用,以便能够为客户端提供新实例。