#c# #asp.net-core #singleton #dispose
#c# #asp.net-core #синглтон #утилизировать
Вопрос:
Учитывая, что у меня есть следующий код, который предоставляется в виде одноэлементного пожизненного сервиса.net core, как я могу безопасно утилизировать клиент (он реализует IDisposable) и создать новый. Я обеспокоен тем, что как только я вызову Dispose старого клиента, он будет удален, и тем временем все вызывающие, которые извлекли клиент, будут указывать на клиент, который теперь удален.
public class MyClientFactory: IMyClientFactory
{
private Client { get; set; }
public async Task<IMyClient> GetClient()
{
if (this.Client != null amp;amp; DoSomeChecksToSeeIfValid())
{
return this.Client;
}
else
{
this.Client?.Dispose();
this.Client = new MyClient(await DoSomethingToGetNewCredentials());
return this.Client;
}
}
}
Ответ №1:
Если вы хотите контролировать время жизни, лучше не возвращать экземпляр объекта. Но если это вас не устраивает, вы можете использовать модель событий.
public interface IMyClientManager
{
void Do(Action<MyClient> action);
}
public interface IMyClient : IDisposable
{
}
public sealed class MyClient: IMyClient
{
public delegate void DisposeHandle();
public event DisposeHandle DisposeEvent;
private bool _isDispose;
public void Dispose()
{
if (!_isDispose)
DisposeEvent?.Invoke();
_isDispose = true;
}
}
public class MyClientManager : IMyClientManager
{
private MyClient Client { get; set; }
private object _sync = new object();
private bool DoSomeChecksToSeeIfValid()
{
return this.Client != null;
}
public void Do(Action<MyClient> action)
{
// you can create connection pull
while (!DoSomeChecksToSeeIfValid())
{
InitClient();
//todo: connect or setup
}
action.Invoke(this.Client);
}
private void InitClient()
{
if (this.Client == null)
{
lock (_sync)
{
this.Client ??= new MyClient();
this.Client.DisposeEvent = Client_DisposeEvent;
}
}
}
public MyClient Create()
{
// you can create connection pull
while (!DoSomeChecksToSeeIfValid())
{
InitClient();
}
return this.Client;
}
private void Client_DisposeEvent()
{
lock (_sync)
{
this.Client.DisposeEvent-= Client_DisposeEvent;
this.Client = null;
}
}
}