我有一个产生随机错误的网络服务,我想我发现了这个错误。
基本上,它是按如下方式读取配置文件,然后加载到XmlDocument:
var config = File.ReadAllText(filename);
xmlDoc.Load(config);
但是,稍后(可能是一秒钟之后)其中一个配置值会更新并保存文件
xmlDoc.Save(filename);
所以我现在遇到了更多错误(不幸的是原始开发人员在第一次READ操作中添加了一个空的try块,所以我现在无法检查),我认为这是因为它&# 39;尝试读取文件就像从IIS生成的另一个进程在.Save部分。我不知道File.ReadAllText如何工作以及它是否会在写锁定文件上失败。
处理此问题的最佳解决方案是什么,以确保阅读始终有效?正在写的值只是一个计数器,如果它失败则会被忽略,因为它不是那么重要但是更喜欢写的。我想我可以把它放到一个单独的配置文件中,然后查看错误,但我觉得它只是一个文件。
感谢。
答案 0 :(得分:3)
您可以使用锁定来确保在写入和反之前完成读取。如:
using System;
using System.Threading;
class Program
{
static readonly object _fileAccess = new object();
static void Write()
{
// Obtain lock and write
lock (_fileAccess)
{
// Write data to filename
xmlDoc.Save(filename);
}
}
static void Read()
{
// Obtain lock and read
lock (_fileAccess)
{
// Read some data from filename
xmlDoc.load(filename);
}
}
static void Main()
{
ThreadStart writeT = new ThreadStart(Write);
new Thread(writeT).Start();
ThreadStart readT = new ThreadStart(Read);
new Thread(readT).Start();
}
}
使用锁定,Read()必须等待Write()完成,Write()必须等待Read()完成。
答案 1 :(得分:0)
要回答关于File.ReadAllText()
如何运作的问题,查看来源,它会在内部使用StreamReader
,而FileStream
会使用FileAccess.Read
和FileShare.Read
打开XmlDocument.Save()
1}},以便在ReadAllText
完成之前阻止任何其他进程写入文件(例如您的XmlDocument.Save()
)。
与此同时,您的FileStream
最终使用了FileAccess.Write
FileShare.Read
和File.ReadAllText()
,只要在Save
之前ReadAllText
开始,就会允许ID
123456789.
234567890.
。
参考文献:https://referencesource.microsoft.com/#mscorlib/system/io/streamreader.cs,a820588d8233a829
https://referencesource.microsoft.com/#System.Xml/System/Xml/Dom/XmlDocument.cs,1db4dba15523d588