AX Agent 진행 시간·글로우 경로 정리 및 최근 로컬 변경 일괄 반영
- AX Agent 스트리밍 경과 시간을 공용 helper로 통일해 비정상적인 수천만 시간 표시를 방지함 - 채팅 입력창 글로우를 런처와 같은 표시/숨김 중심의 얇은 외곽 글로우로 정리하고 런처 글로우 설정은 일반 설정에 유지함 - README와 DEVELOPMENT 문서를 2026-04-08 12:02 (KST) 기준으로 갱신하고 Release 빌드 경고 0 / 오류 0을 확인함
This commit is contained in:
@@ -162,13 +162,44 @@ public class SettingsService
|
||||
return string.Compare(current, target, StringComparison.Ordinal) < 0;
|
||||
}
|
||||
|
||||
private static readonly object _saveLock = new();
|
||||
|
||||
public void Save()
|
||||
{
|
||||
EnsureDirectories();
|
||||
NormalizeRuntimeSettings();
|
||||
var json = JsonSerializer.Serialize(_settings, JsonOptions);
|
||||
var encrypted = CryptoService.PortableEncrypt(json);
|
||||
File.WriteAllText(SettingsPath, encrypted);
|
||||
|
||||
// 임시 파일에 쓰고 교체 (atomic write) — 동시 읽기 충돌 방지
|
||||
lock (_saveLock)
|
||||
{
|
||||
var tmpPath = SettingsPath + ".tmp";
|
||||
for (int attempt = 0; attempt < 3; attempt++)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.WriteAllText(tmpPath, encrypted);
|
||||
// File.Move with overwrite (atomic on NTFS)
|
||||
File.Move(tmpPath, SettingsPath, overwrite: true);
|
||||
break;
|
||||
}
|
||||
catch (IOException) when (attempt < 2)
|
||||
{
|
||||
Thread.Sleep(50 * (attempt + 1));
|
||||
}
|
||||
catch (Exception ex) when (attempt < 2)
|
||||
{
|
||||
LogService.Warn($"settings.dat 저장 재시도 {attempt + 1}/3: {ex.Message}");
|
||||
Thread.Sleep(50 * (attempt + 1));
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 임시 파일 잔여 방지
|
||||
try { if (File.Exists(tmpPath)) File.Delete(tmpPath); } catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
SettingsChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user