From 4afa7aa9166df0694966e3c3f7ea08c458ea7862 Mon Sep 17 00:00:00 2001 From: lindexi Date: Sun, 22 Aug 2021 21:08:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E4=B8=8A=E7=BA=BF=E7=A8=8B=E8=B0=83?= =?UTF-8?q?=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IMainThreadDispatcher.cs | 18 +++++++ .../StartupManager.cs | 52 +++++++++++-------- 2 files changed, 47 insertions(+), 23 deletions(-) create mode 100644 src/dotnetCampus.ApplicationStartupManager/IMainThreadDispatcher.cs diff --git a/src/dotnetCampus.ApplicationStartupManager/IMainThreadDispatcher.cs b/src/dotnetCampus.ApplicationStartupManager/IMainThreadDispatcher.cs new file mode 100644 index 0000000..d605cee --- /dev/null +++ b/src/dotnetCampus.ApplicationStartupManager/IMainThreadDispatcher.cs @@ -0,0 +1,18 @@ +using System; +using System.Threading.Tasks; + +namespace dotnetCampus.ApplicationStartupManager +{ + /// + /// 主线程执行调度 + /// + public interface IMainThreadDispatcher + { + /// + /// 调度执行 + /// + /// + /// + Task InvokeAsync(Action action); + } +} \ No newline at end of file diff --git a/src/dotnetCampus.ApplicationStartupManager/StartupManager.cs b/src/dotnetCampus.ApplicationStartupManager/StartupManager.cs index 4ee97fa..e33f124 100644 --- a/src/dotnetCampus.ApplicationStartupManager/StartupManager.cs +++ b/src/dotnetCampus.ApplicationStartupManager/StartupManager.cs @@ -14,6 +14,8 @@ namespace dotnetCampus.ApplicationStartupManager { public class StartupManager : IStartupManager //, IStartupManagerLegacy { + private readonly IMainThreadDispatcher _dispatcher; + /// /// Builder 模式所需状态:包含当前剩余需要管理的启动任务程序集。 /// @@ -47,7 +49,7 @@ namespace dotnetCampus.ApplicationStartupManager private IStartupLogger Logger => Context.Logger; public StartupManager(IStartupLogger logger, FileConfigurationRepo configurationRepo, - Func fastFailAction) + Func fastFailAction, IMainThreadDispatcher dispatcher) { if (logger == null) { @@ -59,6 +61,8 @@ namespace dotnetCampus.ApplicationStartupManager throw new ArgumentNullException(nameof(configurationRepo)); } + _dispatcher = dispatcher; + ThreadPool.GetMinThreads(out _workerThreads, out _completionPortThreads); //启动期间存在大量的线程池调用(包含IO操作),而创建的多数线程在等待 IO 时都是不会被调度的 //设置更多的初始化线程数可以减少启动期间的线程调度等待 @@ -99,7 +103,7 @@ namespace dotnetCampus.ApplicationStartupManager /// 使用此方法可以添加一些虚拟的,实际上不会执行任何启动任务的关键启动节点,用于汇总其他模块的依赖关系。 /// /// - public StartupManager UseCriticalNodes( params string[] criticalNodeKeys) + public StartupManager UseCriticalNodes(params string[] criticalNodeKeys) { if (criticalNodeKeys == null) { @@ -165,7 +169,7 @@ namespace dotnetCampus.ApplicationStartupManager wrapper.StartupTask = new NullObjectStartup(); wrapper.Categories = StartupCategory.All; - if (beforeTasks?.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries) is string[] before) + if (beforeTasks?.Split(new[] {";"}, StringSplitOptions.RemoveEmptyEntries) is string[] before) { foreach (var b in before) { @@ -174,7 +178,7 @@ namespace dotnetCampus.ApplicationStartupManager } } - if (afterTasks?.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries) is string[] after) + if (afterTasks?.Split(new[] {";"}, StringSplitOptions.RemoveEmptyEntries) is string[] after) { foreach (var a in after) { @@ -193,7 +197,8 @@ namespace dotnetCampus.ApplicationStartupManager return this; } - public StartupManager ForStartupTasksOfCategory(StartupCategory category, Action taskBuilder) + public StartupManager ForStartupTasksOfCategory(StartupCategory category, + Action taskBuilder) { _additionalBuilders.Add(builder => { @@ -213,13 +218,13 @@ namespace dotnetCampus.ApplicationStartupManager Logger.RecordTime("GraphBuilded"); } - // todo dispatcher var dispatcher = Application.Current.Dispatcher; + var dispatcher = _dispatcher; foreach (var wrapper in Graph) { var startupTasks = wrapper.Dependencies.Select(s => GetStartupTaskWrapper(s).StartupTask); if (wrapper.UIOnly) { - // todo dispatcher await dispatcher.InvokeAsync(() => wrapper.ExecuteTask(startupTasks, Context)); + await dispatcher.InvokeAsync(() => wrapper.ExecuteTask(startupTasks, Context)); } else { @@ -231,22 +236,21 @@ namespace dotnetCampus.ApplicationStartupManager Logger.RecordTime("AllStartupTasksCompleted"); - // todo dispatcher -// Debug.WriteLine(Logger); -//#pragma warning disable CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法 -// dispatcher.InvokeAsync(() => -// Logger.ReportResult(Graph.OfType().ToList())); -//#pragma warning restore CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法 + Debug.WriteLine(Logger); +#pragma warning disable CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法 + dispatcher.InvokeAsync(() => + Logger.ReportResult(Graph.OfType().ToList())); +#pragma warning restore CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法 ThreadPool.SetMinThreads(Math.Max(_workerThreads, 8), Math.Max(_completionPortThreads, 8)); } - public void RunLegacy(StartupTask task) - { -#pragma warning disable CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法 - task.JoinAsync(null, true); -#pragma warning restore CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法 - } +// public void RunLegacy(StartupTask task) +// { +//#pragma warning disable CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法 +// task.JoinAsync(null, true); +//#pragma warning restore CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法 +// } private List BuildStartupGraph() { @@ -314,7 +318,8 @@ namespace dotnetCampus.ApplicationStartupManager void AddDependencies(StartupTaskWrapper wrapper, string afterTasks) { - foreach (var task in afterTasks.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(CompatibleTaskName)) + foreach (var task in afterTasks.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries) + .Select(CompatibleTaskName)) { if (!taskMetadataList.Exists(metadata => metadata.Key == task) && !wrappers.Exists(taskWrapper => taskWrapper.StartupTaskKey == task)) @@ -333,7 +338,8 @@ namespace dotnetCampus.ApplicationStartupManager void AddFollowTasks(StartupTaskWrapper wrapper, string beforeTasks) { - foreach (var task in beforeTasks.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(CompatibleTaskName)) + foreach (var task in beforeTasks.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries) + .Select(CompatibleTaskName)) { if (!taskMetadataList.Exists(metadata => metadata.Key == task) && !wrappers.Exists(taskWrapper => taskWrapper.StartupTaskKey == task)) @@ -404,7 +410,7 @@ namespace dotnetCampus.ApplicationStartupManager time = DFSVisit(wrapper, time); } } - + visitWrapper.VisitedFinishTime = time + 1; visitWrapper.IsVisited = VisitState.Visited; return visitWrapper.VisitedFinishTime; @@ -440,4 +446,4 @@ namespace dotnetCampus.ApplicationStartupManager private static string StartupTypeToKey(Type type) => type.Name.Remove(type.Name.Length - "startup".Length); } -} +} \ No newline at end of file