gpt4 book ai didi

c# - 如何从 C# Web API REST 服务器缓存缓慢的资源初始化?

转载 作者:太空宇宙 更新时间:2023-11-03 14:44:52 25 4
gpt4 key购买 nike

上下文

我正在尝试实现“包装”现有 C 程序的 REST API 网络服务。

问题/目标

鉴于 C 程序在我告诉它打开特定文件夹时初始化时间慢且 RAM 使用率高(假设这无法改进),我正在考虑缓存 C 句柄/对象,所以下一次 GET请求命中同一个文件夹,我可以使用现有的句柄。

我尝试过的

首先声明一个从文件夹路径到句柄的静态字典映射:

static ConcurrentDictionary<string, IHandle> handles = new ConcurrentDictionary<string, IHandle>();

在我的 GET 函数中:

IHandle theHandle = handles.GetOrAdd(dir.Name, x => {
return new Handle(x); //this is the slow and memory-intensive function
});

这样,无论何时之前已获取特定文件夹,它都会有一个可供我使用的句柄。

为什么不好

因此,如果同时缓存了太多文件夹,我将面临内存不足的风险。如何将类似 GC 的后台进程添加到 TryRemove()并调用IHandle.Dispose()在旧句柄上,也许在最近最少使用或最不经常使用的策略中?理想情况下,它应该仅在可用物理内存不足时才开始触发。

我试过在 GET 函数中添加如下语句,但是看起来太 hacky 了,而且功能非常有限。仅当我总是希望句柄在 10 秒后过期时,这种方法才有效,并且如果后续请求在 10 秒内到达,它不会重新启动计时器。

HostingEnvironment.QueueBackgroundWorkItem(ct =>
{
System.Threading.Thread.Sleep(10000);
if (handles.TryRemove(dir.Name, out var handle2))
handle2.Dispose();
});

这个问题不是什么

我不认为缓存输出是这里的解决方案。在我返回这个 GET 请求的结果(它只是文件夹内容的元数据)之后,可能会有另一个 GET 请求更深入的数据,这需要调用 Handle的方法。

我希望我的问题足够清楚!

最佳答案

  1. 处理内存不足时的关闭。
ConcurrentQueue<(string, IHandle)> handles = new ConcurrentQueue<(string, IHandle)>();

void CheckMemory_OptionallyReleaseOldHandles()
{
var performance = new System.Diagnostics.PerformanceCounter("Memory", "Available MBytes");

while (performance.NextValue() <= YOUR_TRESHHOLD)
{
if (handles.TryDequeue(out ValueTuple<string, IHandle> value))
{
value.Item2.Dispose();
}
}
}
  1. 您的 Get 方法。
IHandle GetHandle()
{
IHandle theHandle = handles.FirstOrDefault(v => v.Item1 == dir.Name).Item2;

if (theHandle == null)
{
theHandle = new Handle(dir.Name);
handles.Enqueue((dir.Name, theHandle));
}

return theHandle;
});
  1. 您的后台任务。
void SetupMemoryCheck()
{

Action<CancellationToken> BeCheckingTheMemory = ct =>
{

for(;;)
{
if (ct.IsCancellationRequested)
{
break;
}

CheckMemory_OptionallyReleaseOldHandles();
Thread.Sleep(500);
};
};

HostingEnvironment.QueueBackgroundWorkItem(ct =>
{
var tf = new TaskFactory(ct, TaskCreationOptions.LongRunning, TaskContinuationOptions.None, TaskScheduler.Current);
tf.StartNew(() => BeCheckingTheMemory(ct));
});
}

我想这个集合将只有很少的元素,所以不需要字典。

关于c# - 如何从 C# Web API REST 服务器缓存缓慢的资源初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54920897/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com