加上线程调度
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace dotnetCampus.ApplicationStartupManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主线程执行调度
|
||||||
|
/// </summary>
|
||||||
|
public interface IMainThreadDispatcher
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 调度执行
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task InvokeAsync(Action action);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,8 @@ namespace dotnetCampus.ApplicationStartupManager
|
|||||||
{
|
{
|
||||||
public class StartupManager : IStartupManager //, IStartupManagerLegacy
|
public class StartupManager : IStartupManager //, IStartupManagerLegacy
|
||||||
{
|
{
|
||||||
|
private readonly IMainThreadDispatcher _dispatcher;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Builder 模式所需状态:包含当前剩余需要管理的启动任务程序集。
|
/// Builder 模式所需状态:包含当前剩余需要管理的启动任务程序集。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -47,7 +49,7 @@ namespace dotnetCampus.ApplicationStartupManager
|
|||||||
private IStartupLogger Logger => Context.Logger;
|
private IStartupLogger Logger => Context.Logger;
|
||||||
|
|
||||||
public StartupManager(IStartupLogger logger, FileConfigurationRepo configurationRepo,
|
public StartupManager(IStartupLogger logger, FileConfigurationRepo configurationRepo,
|
||||||
Func<Exception, Task> fastFailAction)
|
Func<Exception, Task> fastFailAction, IMainThreadDispatcher dispatcher)
|
||||||
{
|
{
|
||||||
if (logger == null)
|
if (logger == null)
|
||||||
{
|
{
|
||||||
@@ -59,6 +61,8 @@ namespace dotnetCampus.ApplicationStartupManager
|
|||||||
throw new ArgumentNullException(nameof(configurationRepo));
|
throw new ArgumentNullException(nameof(configurationRepo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_dispatcher = dispatcher;
|
||||||
|
|
||||||
ThreadPool.GetMinThreads(out _workerThreads, out _completionPortThreads);
|
ThreadPool.GetMinThreads(out _workerThreads, out _completionPortThreads);
|
||||||
//启动期间存在大量的线程池调用(包含IO操作),而创建的多数线程在等待 IO 时都是不会被调度的
|
//启动期间存在大量的线程池调用(包含IO操作),而创建的多数线程在等待 IO 时都是不会被调度的
|
||||||
//设置更多的初始化线程数可以减少启动期间的线程调度等待
|
//设置更多的初始化线程数可以减少启动期间的线程调度等待
|
||||||
@@ -99,7 +103,7 @@ namespace dotnetCampus.ApplicationStartupManager
|
|||||||
/// 使用此方法可以添加一些虚拟的,实际上不会执行任何启动任务的关键启动节点,用于汇总其他模块的依赖关系。
|
/// 使用此方法可以添加一些虚拟的,实际上不会执行任何启动任务的关键启动节点,用于汇总其他模块的依赖关系。
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public StartupManager UseCriticalNodes( params string[] criticalNodeKeys)
|
public StartupManager UseCriticalNodes(params string[] criticalNodeKeys)
|
||||||
{
|
{
|
||||||
if (criticalNodeKeys == null)
|
if (criticalNodeKeys == null)
|
||||||
{
|
{
|
||||||
@@ -165,7 +169,7 @@ namespace dotnetCampus.ApplicationStartupManager
|
|||||||
wrapper.StartupTask = new NullObjectStartup();
|
wrapper.StartupTask = new NullObjectStartup();
|
||||||
wrapper.Categories = StartupCategory.All;
|
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)
|
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)
|
foreach (var a in after)
|
||||||
{
|
{
|
||||||
@@ -193,7 +197,8 @@ namespace dotnetCampus.ApplicationStartupManager
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StartupManager ForStartupTasksOfCategory(StartupCategory category, Action<StartupTaskBuilder> taskBuilder)
|
public StartupManager ForStartupTasksOfCategory(StartupCategory category,
|
||||||
|
Action<StartupTaskBuilder> taskBuilder)
|
||||||
{
|
{
|
||||||
_additionalBuilders.Add(builder =>
|
_additionalBuilders.Add(builder =>
|
||||||
{
|
{
|
||||||
@@ -213,13 +218,13 @@ namespace dotnetCampus.ApplicationStartupManager
|
|||||||
Logger.RecordTime("GraphBuilded");
|
Logger.RecordTime("GraphBuilded");
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo dispatcher var dispatcher = Application.Current.Dispatcher;
|
var dispatcher = _dispatcher;
|
||||||
foreach (var wrapper in Graph)
|
foreach (var wrapper in Graph)
|
||||||
{
|
{
|
||||||
var startupTasks = wrapper.Dependencies.Select(s => GetStartupTaskWrapper(s).StartupTask);
|
var startupTasks = wrapper.Dependencies.Select(s => GetStartupTaskWrapper(s).StartupTask);
|
||||||
if (wrapper.UIOnly)
|
if (wrapper.UIOnly)
|
||||||
{
|
{
|
||||||
// todo dispatcher await dispatcher.InvokeAsync(() => wrapper.ExecuteTask(startupTasks, Context));
|
await dispatcher.InvokeAsync(() => wrapper.ExecuteTask(startupTasks, Context));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -231,22 +236,21 @@ namespace dotnetCampus.ApplicationStartupManager
|
|||||||
|
|
||||||
Logger.RecordTime("AllStartupTasksCompleted");
|
Logger.RecordTime("AllStartupTasksCompleted");
|
||||||
|
|
||||||
// todo dispatcher
|
Debug.WriteLine(Logger);
|
||||||
// Debug.WriteLine(Logger);
|
#pragma warning disable CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
|
||||||
//#pragma warning disable CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
|
dispatcher.InvokeAsync(() =>
|
||||||
// dispatcher.InvokeAsync(() =>
|
Logger.ReportResult(Graph.OfType<IStartupTaskWrapper>().ToList()));
|
||||||
// Logger.ReportResult(Graph.OfType<IStartupTaskWrapper>().ToList()));
|
#pragma warning restore CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
|
||||||
//#pragma warning restore CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
|
|
||||||
|
|
||||||
ThreadPool.SetMinThreads(Math.Max(_workerThreads, 8), Math.Max(_completionPortThreads, 8));
|
ThreadPool.SetMinThreads(Math.Max(_workerThreads, 8), Math.Max(_completionPortThreads, 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RunLegacy(StartupTask task)
|
// public void RunLegacy(StartupTask task)
|
||||||
{
|
// {
|
||||||
#pragma warning disable CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
|
//#pragma warning disable CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
|
||||||
task.JoinAsync(null, true);
|
// task.JoinAsync(null, true);
|
||||||
#pragma warning restore CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
|
//#pragma warning restore CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
|
||||||
}
|
// }
|
||||||
|
|
||||||
private List<StartupTaskWrapper> BuildStartupGraph()
|
private List<StartupTaskWrapper> BuildStartupGraph()
|
||||||
{
|
{
|
||||||
@@ -314,7 +318,8 @@ namespace dotnetCampus.ApplicationStartupManager
|
|||||||
|
|
||||||
void AddDependencies(StartupTaskWrapper wrapper, string afterTasks)
|
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)
|
if (!taskMetadataList.Exists(metadata => metadata.Key == task)
|
||||||
&& !wrappers.Exists(taskWrapper => taskWrapper.StartupTaskKey == task))
|
&& !wrappers.Exists(taskWrapper => taskWrapper.StartupTaskKey == task))
|
||||||
@@ -333,7 +338,8 @@ namespace dotnetCampus.ApplicationStartupManager
|
|||||||
|
|
||||||
void AddFollowTasks(StartupTaskWrapper wrapper, string beforeTasks)
|
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)
|
if (!taskMetadataList.Exists(metadata => metadata.Key == task)
|
||||||
&& !wrappers.Exists(taskWrapper => taskWrapper.StartupTaskKey == task))
|
&& !wrappers.Exists(taskWrapper => taskWrapper.StartupTaskKey == task))
|
||||||
|
|||||||
Reference in New Issue
Block a user