fix racing between AutoSave and process exit

This commit is contained in:
cs8425
2026-04-29 19:30:57 +08:00
parent 5f3fc0c746
commit 7e83d2ccd2
2 changed files with 54 additions and 15 deletions

View File

@@ -14,7 +14,10 @@ public class DatabaseHelper
public static readonly ConcurrentDictionary<int, List<BaseDatabaseDataHelper>> UidInstanceMap = [];
public static readonly List<int> ToSaveUidList = [];
public static long LastSaveTick = DateTime.UtcNow.Ticks;
public static Thread? SaveThread;
private static int _saving = 0;
private static Task? _saveTask;
private static CancellationTokenSource? _cts;
public static bool LoadAccount;
public static bool LoadAllData;
@@ -80,16 +83,8 @@ public class DatabaseHelper
Thread.Sleep(100);
}
LastSaveTick = DateTime.UtcNow.Ticks;
SaveThread = new Thread(async () =>
{
while (true) {
CalcSaveDatabase();
await Task.Delay(100);
}
});
SaveThread.Start();
_cts = new CancellationTokenSource();
_saveTask = RunAutoSave(_cts.Token);
LoadAllData = true;
}
@@ -252,6 +247,35 @@ public class DatabaseHelper
ToSaveUidList.RemoveAll(x => x == key);
}
public static void Stop()
{
_cts?.Cancel();
}
public static async Task WaitAsync()
{
if (_saveTask != null)
await _saveTask;
}
private static async Task RunAutoSave(CancellationToken token)
{
LastSaveTick = DateTime.UtcNow.Ticks;
try
{
while (!token.IsCancellationRequested)
{
CalcSaveDatabase();
await Task.Delay(100, token);
}
}
catch (OperationCanceledException)
{
// exit normally
// Console.WriteLine($"RunAutoSave exit! - OperationCanceledException");
}
}
// Auto save per 5 min
public static void CalcSaveDatabase()
{
@@ -261,6 +285,10 @@ public class DatabaseHelper
public static void SaveDatabase()
{
// ensure only one SaveDatabase() runnig
if (Interlocked.Exchange(ref _saving, 1) == 1)
return;
try
{
var prev = DateTime.Now;
@@ -285,11 +313,18 @@ public class DatabaseHelper
Math.Round(t, 2).ToString(CultureInfo.InvariantCulture)));
ToSaveUidList.Clear();
// Thread.Sleep(5000); // for test if saving process taking too long
}
catch (Exception e)
{
logger.Error("An error occurred while saving the database", e);
}
finally
{
// release lock
Volatile.Write(ref _saving, 0);
}
LastSaveTick = DateTime.UtcNow.Ticks;
}