优化模块资源释放与异步预加载
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user