优化模块资源释放与异步预加载

This commit is contained in:
2026-09-03 14:16:48 +08:00
parent a263522b47
commit fddab16bd2
35 changed files with 1553 additions and 977 deletions
+53 -1
View File
@@ -4,11 +4,63 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Lskj.Util
{
public class TaskSchedulerUtil : TaskScheduler
{
/// <summary>
/// WinForms 会在后台线程第一次构造控件时自动安装
/// WindowsFormsSynchronizationContext。预加载任务只能执行数据准备,
/// 不应把线程池线程注册成 WinForms UI 线程;否则 DevExpress manager
/// 会绑定到已经没有消息循环的线程,导致模块打开/关闭后的残留和卡死。
/// 这里只在线程池任务执行期间使用一个非 WinForms 的同步上下文
/// 作为占位,不改变调度器的并发度,也不触碰真正的 UI 线程上下文。
/// 不能直接使用 SynchronizationContext 基类实例:WinForms 的
/// InstallIfNeeded 会把“基类实例”视为未安装状态并再次替换为
/// WindowsFormsSynchronizationContext;必须使用独立派生类型。
/// </summary>
private void ExecuteTaskWithoutWinFormsContext(Task task)
{
SynchronizationContext previousContext =
SynchronizationContext.Current;
bool replaceContext = previousContext == null ||
previousContext is WindowsFormsSynchronizationContext;
if (replaceContext)
{
SynchronizationContext.SetSynchronizationContext(
new BackgroundSynchronizationContext());
}
try
{
TryExecuteTask(task);
}
finally
{
if (replaceContext)
{
SynchronizationContext.SetSynchronizationContext(
previousContext);
}
}
}
/// <summary>
/// 标记后台线程已明确配置同步上下文,阻止 WinForms 按“空/基类上下文”
/// 自动安装 WindowsFormsSynchronizationContext。继承基类的默认 Post
/// 实现仍将延续任务投递到线程池,不改变普通后台任务语义。
/// </summary>
private sealed class BackgroundSynchronizationContext : SynchronizationContext
{
public override SynchronizationContext CreateCopy()
{
return new BackgroundSynchronizationContext();
}
}
private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); //任务队列
private readonly int _maxDegreeOfParallelism; //最大并发线程数
private int _runningTasks = 0; //当前正在运行的线程数
@@ -46,7 +98,7 @@ namespace Lskj.Util
{
try
{
base.TryExecuteTask(task); // 执行任务
ExecuteTaskWithoutWinFormsContext(task);
}
finally
{