asp.net-core - 如何在 ASP NET 中将内存数据与磁盘同步
问题描述
在 ASP NET 控制器中,我有一个返回项目列表的服务。该服务从 RAM 将列表提供给请求者。该列表也可以由一组特殊的用户更改,因此每次更改时,我都会将更改写入磁盘并从磁盘更新我的 RAM。(以这种方式阅读我自己的作品)
当我更改此列表时,来自JS
客户端的更改已正确写入磁盘,但是当我转发第二个请求以获取我的列表时,我收到了一个陈旧的列表。我需要按 F5 让客户端获取正确的数据.
我不明白 RAM 缓存是如何落后的。您可以在下面的服务中看到我已经用 . 保护了更改方法lock
。我也尝试过没有它但无济于事。
服务
public class FileService : IADReadWrite {
private const int SIZE = 5;
private const string COMPUTER_FILE = @"computers.txt";
private List<Computer> computers = new List<Computer>();
private readonly object @filelock = new object();
private readonly Computer[] DEFAULT_COMPUTERS_LIST = new Computer[] {
new Computer(id:"W-CZC81371RS",Username:"A"),
new Computer(id:"W-CZC81371RQ",Username:"B"),
};
async Task<Computers> GetComputersAsymc() {
if (this.computers.Count == 0) {
var query = await Fetch();
this.computers = query.ToList();
}
var result = new Computers(this.computers);
return result;
}
public async Task<bool> AddComputerAsync(Computer computer) {
lock (filelock) {
if (this.computers.Any(x => x == computer)) {
return false;
}
this.computers.Add(computer);
File.WriteAllText(COMPUTER_FILE, JsonConvert.SerializeObject(this.computers, Formatting.Indented));
this.computers = JsonConvert.DeserializeObject<List<Computer>>(File.ReadAllText(COMPUTER_FILE));
}
return true;
}
---------------------Helpers --------------------------
private async Task<IEnumerable<Computer>> Fetch() {
if (!File.Exists(COMPUTER_FILE)) {
WriteComputersToDisk();
}
using (FileStream stream = new FileStream(COMPUTER_FILE, FileMode.Open, FileAccess.Read)) {
var raw = await File.ReadAllTextAsync(COMPUTER_FILE);
var comp = JsonConvert.DeserializeObject<List<Computer>>(raw);
return comp;
}
}
private void WriteComputersToDisk() {
var comps = DEFAULT_COMPUTERS_LIST;
var data = JsonConvert.SerializeObject(comps, Formatting.Indented);
File.WriteAllText(COMPUTER_FILE, data);
}
}
控制器
public class MyController:Controller
{
MyController(IADReadWrite service)
{
this.service=service;
}
IADReadWrite service;
[HttpGet]
public async Task<List<Computer>> GetAll()
{
return await service.GetComputersAsync();
}
[HttpPost]
public async Task AddComputer(Computer computer)
{
await service.AddComputerAsync(computer);
}
}
设想
Initial list : [0,1]
Client hits controller calling `AddComputer` {2}
I check the file , list is now: [0,1,2]
Client hits controller calling `GetComputers` -> it returns [0,1]
I hit F5 on the browser -> GetComputers gets hit again -> it returns [0,1,2]
PS
我没有发布这个Computer
类,因为在这种情况下它并不重要(它实现IEquateable
以防你想知道当我使用==
运算符时它是否失败。最后两种方法处理磁盘文件的初始化。
解决方案
推荐阅读
- javascript - 如何在反应中过滤和合并两个数组
- c# - 使用 GemBox 将数据从 DataGridView 导入现有 Excel 文件
- c# - 获取开放的泛型类型列表 .Net Core
- django - 更新 docker 卷的静态文件
- visual-studio-2019 - 尝试启动新的 Web 项目时出现包安装错误
- github - 需要在 Jekyll 中获取服务器 url 字符串
- r - 数据集中所有可能的组合与在 R 中按顺序排列的嵌套组
- java - -Xcomp 可以在源代码中而不是在 java 编译器参数中吗?
- javascript - 我的 discord.js 机器人的 sql 没有/不能从我的 sqlite3 db 定义一个表
- node.js - 如何使用使用 mongodb 的用户向特定用户发出通知