From bad6c1b10890087e25a5fae60f706dc3bdad2593 Mon Sep 17 00:00:00 2001 From: gewuyou <95328647+GeWuYou@users.noreply.github.com> Date: Sat, 25 Apr 2026 09:34:19 +0800 Subject: [PATCH] =?UTF-8?q?fix(game):=20=E6=B8=85=E7=90=86=20FileStorage?= =?UTF-8?q?=20=E5=BC=82=E6=AD=A5=E5=AD=98=E5=82=A8=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E7=9A=84=20MA0004?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复 FileStorage 在锁获取与异步释放路径上的 ConfigureAwait(false) 缺失 - 保持文件锁、临时文件写入和原子替换流程不变 --- GFramework.Game/Storage/FileStorage.cs | 107 +++++++++++++------------ 1 file changed, 56 insertions(+), 51 deletions(-) diff --git a/GFramework.Game/Storage/FileStorage.cs b/GFramework.Game/Storage/FileStorage.cs index 383c0298..6d819f34 100644 --- a/GFramework.Game/Storage/FileStorage.cs +++ b/GFramework.Game/Storage/FileStorage.cs @@ -143,11 +143,11 @@ public sealed class FileStorage : IFileStorage, IDisposable ObjectDisposedException.ThrowIf(_disposed, this); var path = ToPath(key); - await using (await _lockManager.AcquireLockAsync(path).ConfigureAwait(false)) - { - if (File.Exists(path)) - File.Delete(path); - } + var pathLock = await _lockManager.AcquireLockAsync(path).ConfigureAwait(false); + await using var configuredPathLock = pathLock.ConfigureAwait(false); + + if (File.Exists(path)) + File.Delete(path); } #endregion @@ -178,10 +178,10 @@ public sealed class FileStorage : IFileStorage, IDisposable ObjectDisposedException.ThrowIf(_disposed, this); var path = ToPath(key); - await using (await _lockManager.AcquireLockAsync(path).ConfigureAwait(false)) - { - return File.Exists(path); - } + var pathLock = await _lockManager.AcquireLockAsync(path).ConfigureAwait(false); + await using var configuredPathLock = pathLock.ConfigureAwait(false); + + return File.Exists(path); } #endregion @@ -236,23 +236,24 @@ public sealed class FileStorage : IFileStorage, IDisposable ObjectDisposedException.ThrowIf(_disposed, this); var path = ToPath(key); - await using (await _lockManager.AcquireLockAsync(path).ConfigureAwait(false)) - { - if (!File.Exists(path)) - throw new FileNotFoundException($"Storage key not found: {key}", path); + var pathLock = await _lockManager.AcquireLockAsync(path).ConfigureAwait(false); + await using var configuredPathLock = pathLock.ConfigureAwait(false); - await using var fs = new FileStream( - path, - FileMode.Open, - FileAccess.Read, - FileShare.Read, - _bufferSize, - useAsync: true); + if (!File.Exists(path)) + throw new FileNotFoundException($"Storage key not found: {key}", path); - using var sr = new StreamReader(fs, Encoding.UTF8); - var content = await sr.ReadToEndAsync().ConfigureAwait(false); - return _serializer.Deserialize(content); - } + var fs = new FileStream( + path, + FileMode.Open, + FileAccess.Read, + FileShare.Read, + _bufferSize, + useAsync: true); + await using var configuredFileStream = fs.ConfigureAwait(false); + + using var sr = new StreamReader(fs, Encoding.UTF8); + var content = await sr.ReadToEndAsync().ConfigureAwait(false); + return _serializer.Deserialize(content); } #endregion @@ -354,38 +355,42 @@ public sealed class FileStorage : IFileStorage, IDisposable var path = ToPath(key); var tempPath = path + ".tmp"; - await using (await _lockManager.AcquireLockAsync(path).ConfigureAwait(false)) + var pathLock = await _lockManager.AcquireLockAsync(path).ConfigureAwait(false); + await using var configuredPathLock = pathLock.ConfigureAwait(false); + + try { - try - { - var content = _serializer.Serialize(value); + var content = _serializer.Serialize(value); - // 先写入临时文件 - await using (var fs = new FileStream( - tempPath, - FileMode.Create, - FileAccess.Write, - FileShare.None, - _bufferSize, - useAsync: true)) - { - await using var sw = new StreamWriter(fs, Encoding.UTF8); - await sw.WriteAsync(content).ConfigureAwait(false); - await sw.FlushAsync().ConfigureAwait(false); - } - - // 原子性替换目标文件 - File.Move(tempPath, path, overwrite: true); - } - catch + // 先写入临时文件 { - // 清理临时文件 - if (File.Exists(tempPath)) - File.Delete(tempPath); - throw; + var fs = new FileStream( + tempPath, + FileMode.Create, + FileAccess.Write, + FileShare.None, + _bufferSize, + useAsync: true); + await using var configuredFileStream = fs.ConfigureAwait(false); + + var sw = new StreamWriter(fs, Encoding.UTF8); + await using var configuredStreamWriter = sw.ConfigureAwait(false); + + await sw.WriteAsync(content).ConfigureAwait(false); + await sw.FlushAsync().ConfigureAwait(false); } + + // 原子性替换目标文件 + File.Move(tempPath, path, overwrite: true); + } + catch + { + // 清理临时文件 + if (File.Exists(tempPath)) + File.Delete(tempPath); + throw; } } #endregion -} \ No newline at end of file +}