mirror of
https://github.com/MikuLeaks/MikuSB.git
synced 2026-06-04 16:43:59 +00:00
fix infinite loop when pressed ctrl+c
This commit is contained in:
@@ -148,13 +148,29 @@ public class IConsole
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public static string ListenConsole()
|
public static async Task ListenConsole(CancellationToken exitToken)
|
||||||
{
|
{
|
||||||
while (true)
|
while (!exitToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
ConsoleKeyInfo keyInfo;
|
ConsoleKeyInfo keyInfo;
|
||||||
try { keyInfo = Console.ReadKey(true); }
|
try
|
||||||
catch (InvalidOperationException) { continue; }
|
{
|
||||||
|
if (!Console.KeyAvailable)
|
||||||
|
{
|
||||||
|
await Task.Delay(10, exitToken);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
keyInfo = Console.ReadKey(true);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
await Task.Delay(50, exitToken);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (keyInfo.Key)
|
switch (keyInfo.Key)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ public class LoaderManager : MikuSB
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void InitCommand()
|
public static async Task InitCommand(CancellationToken exitToken)
|
||||||
{
|
{
|
||||||
// Register the command handlers
|
// Register the command handlers
|
||||||
try
|
try
|
||||||
@@ -178,6 +178,6 @@ public class LoaderManager : MikuSB
|
|||||||
IConsole.OnConsoleExcuteCommand += CommandExecutor.ConsoleExcuteCommand;
|
IConsole.OnConsoleExcuteCommand += CommandExecutor.ConsoleExcuteCommand;
|
||||||
CommandExecutor.OnRunCommand += (sender, e) => { CommandManager.HandleCommand(e, sender); };
|
CommandExecutor.OnRunCommand += (sender, e) => { CommandManager.HandleCommand(e, sender); };
|
||||||
|
|
||||||
IConsole.ListenConsole();
|
await IConsole.ListenConsole(exitToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,10 @@ public class MikuSB
|
|||||||
public static readonly Listener Listener = new();
|
public static readonly Listener Listener = new();
|
||||||
public static readonly CommandManager CommandManager = new();
|
public static readonly CommandManager CommandManager = new();
|
||||||
|
|
||||||
|
// for exit signal
|
||||||
|
private static readonly CancellationTokenSource _cts = new();
|
||||||
|
private static int _exitCode = 0;
|
||||||
|
|
||||||
public static async Task Main()
|
public static async Task Main()
|
||||||
{
|
{
|
||||||
var time = DateTime.Now;
|
var time = DateTime.Now;
|
||||||
@@ -50,11 +54,15 @@ public class MikuSB
|
|||||||
ResourceManager.IsLoaded = true;
|
ResourceManager.IsLoaded = true;
|
||||||
|
|
||||||
HandbookGenerator.GenerateAll();
|
HandbookGenerator.GenerateAll();
|
||||||
LoaderManager.InitCommand();
|
var consoleTask = Task.Run(() => LoaderManager.InitCommand(_cts.Token), _cts.Token);
|
||||||
|
|
||||||
var elapsed = DateTime.Now - time;
|
var elapsed = DateTime.Now - time;
|
||||||
Logger.Info(I18NManager.Translate("Server.ServerInfo.ServerStarted",
|
Logger.Info(I18NManager.Translate("Server.ServerInfo.ServerStarted",
|
||||||
Math.Round(elapsed.TotalSeconds, 2).ToString(CultureInfo.InvariantCulture)));
|
Math.Round(elapsed.TotalSeconds, 2).ToString(CultureInfo.InvariantCulture)));
|
||||||
|
|
||||||
|
await consoleTask;
|
||||||
|
|
||||||
|
ProcessExit(Volatile.Read(ref _exitCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Exit
|
#region Exit
|
||||||
@@ -64,30 +72,36 @@ public class MikuSB
|
|||||||
AppDomain.CurrentDomain.ProcessExit += (_, _) =>
|
AppDomain.CurrentDomain.ProcessExit += (_, _) =>
|
||||||
{
|
{
|
||||||
Logger.Info(I18NManager.Translate("Server.ServerInfo.Shutdown"));
|
Logger.Info(I18NManager.Translate("Server.ServerInfo.Shutdown"));
|
||||||
ProcessExit();
|
RequestShutdown(0);
|
||||||
};
|
};
|
||||||
AppDomain.CurrentDomain.UnhandledException += (obj, arg) =>
|
AppDomain.CurrentDomain.UnhandledException += (obj, arg) =>
|
||||||
{
|
{
|
||||||
Logger.Error(I18NManager.Translate("Server.ServerInfo.UnhandledException", obj.GetType().Name),
|
Logger.Error(I18NManager.Translate("Server.ServerInfo.UnhandledException", obj.GetType().Name),
|
||||||
(Exception)arg.ExceptionObject);
|
(Exception)arg.ExceptionObject);
|
||||||
Logger.Info(I18NManager.Translate("Server.ServerInfo.Shutdown"));
|
Logger.Info(I18NManager.Translate("Server.ServerInfo.Shutdown"));
|
||||||
ProcessExit();
|
RequestShutdown(1);
|
||||||
Environment.Exit(1);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Console.CancelKeyPress += (_, eventArgs) =>
|
Console.CancelKeyPress += (_, eventArgs) =>
|
||||||
{
|
{
|
||||||
Logger.Info(I18NManager.Translate("Server.ServerInfo.CancelKeyPressed"));
|
Logger.Info(I18NManager.Translate("Server.ServerInfo.CancelKeyPressed"));
|
||||||
eventArgs.Cancel = true;
|
eventArgs.Cancel = true;
|
||||||
Environment.Exit(0);
|
RequestShutdown(0);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessExit()
|
private static void RequestShutdown(int exitCode)
|
||||||
|
{
|
||||||
|
Interlocked.Exchange(ref _exitCode, exitCode);
|
||||||
|
_cts.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ProcessExit(int exitCode)
|
||||||
{
|
{
|
||||||
SocketListener.Connections.Values.ToList().ForEach(x => x.Stop(true));
|
SocketListener.Connections.Values.ToList().ForEach(x => x.Stop(true));
|
||||||
DatabaseHelper.SaveThread?.Interrupt();
|
DatabaseHelper.SaveThread?.Interrupt();
|
||||||
DatabaseHelper.SaveDatabase();
|
DatabaseHelper.SaveDatabase();
|
||||||
|
Environment.Exit(exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|||||||
Reference in New Issue
Block a user