using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace FastGithub.Http
{
///
/// 表示LifetimeHttpHandler清理器
///
sealed class LifetimeHttpHandlerCleaner
{
///
/// 当前监视生命周期的记录的数量
///
private int trackingEntryCount = 0;
///
/// 监视生命周期的记录队列
///
private readonly ConcurrentQueue trackingEntries = new();
///
/// 获取或设置清理的时间间隔
/// 默认10s
///
public TimeSpan CleanupInterval { get; set; } = TimeSpan.FromSeconds(10d);
///
/// 添加要清除的httpHandler
///
/// httpHandler
public void Add(LifetimeHttpHandler handler)
{
var entry = new TrackingEntry(handler);
this.trackingEntries.Enqueue(entry);
// 从0变为1,要启动清理作业
if (Interlocked.Increment(ref this.trackingEntryCount) == 1)
{
this.StartCleanup();
}
}
///
/// 启动清理作业
///
private async void StartCleanup()
{
await Task.Yield();
while (this.Cleanup() == false)
{
await Task.Delay(this.CleanupInterval);
}
}
///
/// 清理失效的拦截器
/// 返回是否完全清理
///
///
private bool Cleanup()
{
var cleanCount = this.trackingEntries.Count;
for (var i = 0; i < cleanCount; i++)
{
this.trackingEntries.TryDequeue(out var entry);
Debug.Assert(entry != null);
if (entry.CanDispose == false)
{
this.trackingEntries.Enqueue(entry);
continue;
}
entry.Dispose();
if (Interlocked.Decrement(ref this.trackingEntryCount) == 0)
{
return true;
}
}
return false;
}
///
/// 表示监视生命周期的记录
///
private class TrackingEntry : IDisposable
{
///
/// 用于释放资源的对象
///
private readonly IDisposable disposable;
///
/// 监视对象的弱引用
///
private readonly WeakReference weakReference;
///
/// 获取是否可以释放资源
///
///
public bool CanDispose => this.weakReference.IsAlive == false;
///
/// 监视生命周期的记录
///
/// 激活状态的httpHandler
public TrackingEntry(LifetimeHttpHandler handler)
{
this.disposable = handler.InnerHandler!;
this.weakReference = new WeakReference(handler);
}
///
/// 释放资源
///
public void Dispose()
{
try
{
this.disposable.Dispose();
}
catch (Exception)
{
}
}
}
}
}