c# - Unity 对象引用丢失
问题描述
我正在尝试为我的体素游戏设置保存系统。一切正常,除了由于 System.NullReferenceException 导致保存文件不保存的可能性很小(如 1/8)。
我已经多次查看代码并且很困惑为什么有时会抛出这个异常。在游戏中,我没有将 RegionData 引用设置为 null。我可以再次按“保存”,一切都会正常进行。
[MessagePackObject]
public class RegionData
{
[Key(0)]
public Vector2Int Position { get; set; } = new Vector2Int(0, 0);
[Key(1)]
public ChunkData[][] Chunks { get; set; }
// Used when opening a saved region data.
public RegionData()
{
}
// Used when creating a new region data.
public RegionData(Vector2Int regionPosition)
{
Position = regionPosition;
Chunks = Utilities.CreateJaggedArray<ChunkData[][]>(16, 16);
}
}
public class RegionSaver
{
readonly List<RegionData> pendingRegions;
readonly Queue<RegionData> regionsReady;
static readonly int SaveDelay = 4000;
public RegionSaver()
{
pendingRegions = new List<RegionData>(10);
regionsReady = new Queue<RegionData>(10);
SaveRegionsFromQueue();
}
public async Task AddRegionData(RegionData regionData)
{
if (pendingRegions.Contains(regionData))
return;
pendingRegions.Add(regionData);
await Task.Delay(SaveDelay).ConfigureAwait(false);
if (pendingRegions.Contains(regionData))
{
regionsReady.Enqueue(regionData);
pendingRegions.Remove(regionData);
}
}
// Infinite loop that saves Regions that have been pushed to the queue.
async void SaveRegionsFromQueue()
{
await Task.Run(async () =>
{
while (true)
{
while (regionsReady.Count > 0)
{
var regionData = regionsReady.Dequeue();
// This is were 'regionData' is sometimes null.
try
{
await SaveRegion(regionData).ConfigureAwait(false);
}
catch (Exception e)
{
Debug.LogError($"Error whiles trying to save Region.\nException: {e}");
}
}
await Task.Delay(TimeSpan.FromSeconds(1f)).ConfigureAwait(false);
}
});
}
async Task SaveRegion(RegionData regionData)
{
using (var fileStream = File.Create(
string.Format(RegionLoader.RegionDataFilePath, regionData.Position.x, regionData.Position.y)))
{
await MessagePackSerializer.SerializeAsync(fileStream, regionData, Utilities.Lz4Options)
.ConfigureAwait(false);
}
}
}
如何调用 AddRegionData 方法。Task.Run(() => chunkHandler.RegionSaver.AddRegionData(regionData));
解决方案
我想我解决了我的问题。用ConcurrentQueue和ConcurrentDictionary替换我已经用 Dictionary 替换的 Queue 和 List会导致没有空引用。我不知道并发会导致如此奇怪的问题。
推荐阅读
- python - 如何从 PyCharm 上相同路径中的模块导入特定功能
- python - Discord.py 我想在嵌入中创建一个随机答案
- android - Kotlin:setText 不起作用
- flutter - 如何使用 BLOC 为对象列表创建流和接收器
- parameters - 水晶报表,期间每一天的相同报表
- java - 我可以在同一个 Android 应用程序中做两个不同的 NavDrawers 吗?
- cuda - Nvidia Tesla T4 张量核心基准测试
- javascript - 如何使用 JS 将删除按钮添加到列中?
- javascript - 我应该如何强制 TypeScript 理解这个数组中不会有任何空值?
- visual-studio - DotNet 5 ClickOnce 缺少程序集