fix: synchronize module data cache cleanup

This commit is contained in:
2026-08-15 18:39:26 +08:00
parent d098dde830
commit a65dfab897
11 changed files with 126 additions and 71 deletions
+43 -35
View File
@@ -211,13 +211,14 @@ namespace Lskj.PubModuleDetail
Dictionary<object, Hashtable> dataCaches =
Model != null ? Model.DataCaches : null;
if (dataCaches == null || !AreDataCacheTasksCompleted(dataCaches))
HashSet<Task> completedTasks;
if (dataCaches == null ||
!TryDetachCompletedCacheTasks(dataCaches, out completedTasks))
{
return;
}
DisposeCompletedCacheTasks(dataCaches);
dataCaches.Clear();
DisposeCompletedCacheTasks(completedTasks);
}
/// <summary>
@@ -225,34 +226,10 @@ namespace Lskj.PubModuleDetail
/// Task.Result 在等待时可能创建底层等待对象,仅清空字典
/// 不会立即释放这些句柄。
/// </summary>
private static void DisposeCompletedCacheTasks(
Dictionary<object, Hashtable> dataCaches)
private static void DisposeCompletedCacheTasks(IEnumerable<Task> tasks)
{
HashSet<Task> tasks = new HashSet<Task>();
foreach (Hashtable cache in dataCaches.Values)
{
if (cache == null)
{
continue;
}
foreach (object value in cache.Values)
{
Task task = value as Task;
if (task != null)
{
tasks.Add(task);
}
}
}
foreach (Task task in tasks)
{
if (!task.IsCompleted)
{
continue;
}
try
{
task.Dispose();
@@ -264,27 +241,58 @@ namespace Lskj.PubModuleDetail
}
/// <summary>
/// 并行初始化仍在运行时不能清空缓存字典,后台任务还会读取或追加其中的数据
/// 仅当并行初始化全部完成时,才在同一同步区间摘除缓存任务
/// AddTask 使用同一个字典实例加锁,避免检查后又插入新任务。
/// </summary>
private static bool AreDataCacheTasksCompleted(Dictionary<object, Hashtable> dataCaches)
private static bool TryDetachCompletedCacheTasks(
Dictionary<object, Hashtable> dataCaches,
out HashSet<Task> completedTasks)
{
completedTasks = new HashSet<Task>();
try
{
foreach (Hashtable cacheValues in dataCaches.Values)
lock (dataCaches)
{
foreach (object value in cacheValues.Values)
foreach (Hashtable cacheValues in dataCaches.Values)
{
Task task = value as Task;
if (task != null && !task.IsCompleted)
if (cacheValues == null)
{
return false;
continue;
}
foreach (object value in cacheValues.Values)
{
Task task = value as Task;
if (task == null)
{
continue;
}
try
{
if (!task.IsCompleted)
{
completedTasks.Clear();
return false;
}
}
catch (ObjectDisposedException)
{
continue;
}
completedTasks.Add(task);
}
}
dataCaches.Clear();
}
return true;
}
catch (InvalidOperationException)
{
completedTasks.Clear();
return false;
}
}