C# 监视文本文件中更改的内容可防止写入该文件
我有一个文本文件,文件中的值正在读入应用程序(控制台应用程序)。我想在文本文件中的值更改时更新应用程序中的值。我已经提到了这一点,并做了一些修改。结果是,当我更改文本文件中的值并尝试保存它时,应用程序中的值不会更新,因为无法保存该文件 如果更改文本文件中的值,如何更新应用程序中的值C# 监视文本文件中更改的内容可防止写入该文件,c#,console-application,updates,inotifypropertychanged,C#,Console Application,Updates,Inotifypropertychanged,我有一个文本文件,文件中的值正在读入应用程序(控制台应用程序)。我想在文本文件中的值更改时更新应用程序中的值。我已经提到了这一点,并做了一些修改。结果是,当我更改文本文件中的值并尝试保存它时,应用程序中的值不会更新,因为无法保存该文件 如果更改文本文件中的值,如何更新应用程序中的值 class Program { static void Main(string[] args) { TestClass sample = new Tes
class Program
{
static void Main(string[] args)
{
TestClass sample = new TestClass();
sample.PropertyChanged += new PropertyChangedEventHandler(sample_PropertyChanged);
while (true)
{
using (StreamReader sr = new StreamReader("Testing.txt"))
{
// Read the stream to a string, and write the string to the console.
string str = sr.ReadToEnd();
sample.TestValue = str;
}
}
}
static void sample_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
TestClass sample = (TestClass)sender;
/*
* Use expression behind if you have more the one property instead sample.TestValue
* typeof(TestClass).GetProperty(e.PropertyName).GetValue(sample, null)*/
Console.WriteLine("Value of property {0} was changed! New value is {1}", e.PropertyName, sample.TestValue);
}
}
public class TestClass : INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
string testValue = string.Empty;
public string TestValue
{
get { return testValue; }
set
{
testValue = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("TestValue"));
}
}
}
代码中至少存在三个严重问题:
PropertyChanged
事件PropertyChanged
事件。这不必要地延长了文件保持打开的时间段(事实上,它存在事件处理程序强制文件保持打开任意长时间的风险) while (true)
{
string str = File.ReadAllText("Testing.txt");
sample.TestValue = str;
Thread.Sleep(1000); // sleep for 1 second
}
这是:
public string TestValue
{
get { return testValue; }
set
{
if (testValue != value)
{
testValue = value;
// BUGBUG: Warning! This code is not thread-safe; it is possible for
// the current thread to check `PropertyChanged` just before some other
// thread changes its value to null, and then to try to invoke the handler
// just _after_ that other thread changes its value to null. This is fine
// if you are sure that the event and property are both only ever accessed
// in one single thread. But otherwise, you need to fix this bug, by
// following the normal C# idiom for raising events, i.e. store the field
// value in a local variable, and then if it's non-null, raise the event
// using the local variable's value instead of the event field itself.
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("TestValue"));
}
}
}
请注意上面代码中关于处理事件时可能出现的错误的注释
除此之外,您还可以对代码进行一些其他改进:
file.GetLastWriteTimeUtc()
检查文件的文件修改时间戳,并且仅当时间戳比上次检查的时间戳新时才打开文件进行读取。这将避免不必要地打开文件,减少文件锁定冲突的可能性FileSystemWatcher
为您完成工作,并且仅在引发Changed
事件时读取文件。这样做的主要缺点是,FileSystemWatcher
并不总是(事实上,通常不是)及时通知文件的更改。它最终会引发相应的事件,但它跟踪的目录信息本身并不总是由Windows及时更新的,这会导致在收到更改通知时出现延迟(根据我的经验,最多几十秒)如果您可以接受在收到通知前最多一分钟的延迟,那么我建议
FileSystemWatcher
。否则,只需每秒轮询一次(或不太频繁),或使用#1选项(至少检查修改时间戳)就可以了。代码中至少存在三个严重问题:
PropertyChanged
事件PropertyChanged
事件。这不必要地延长了文件保持打开的时间段(事实上,它存在事件处理程序强制文件保持打开任意长时间的风险) while (true)
{
string str = File.ReadAllText("Testing.txt");
sample.TestValue = str;
Thread.Sleep(1000); // sleep for 1 second
}
这是:
public string TestValue
{
get { return testValue; }
set
{
if (testValue != value)
{
testValue = value;
// BUGBUG: Warning! This code is not thread-safe; it is possible for
// the current thread to check `PropertyChanged` just before some other
// thread changes its value to null, and then to try to invoke the handler
// just _after_ that other thread changes its value to null. This is fine
// if you are sure that the event and property are both only ever accessed
// in one single thread. But otherwise, you need to fix this bug, by
// following the normal C# idiom for raising events, i.e. store the field
// value in a local variable, and then if it's non-null, raise the event
// using the local variable's value instead of the event field itself.
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("TestValue"));
}
}
}
请注意上面代码中关于处理事件时可能出现的错误的注释
除此之外,您还可以对代码进行一些其他改进:
file.GetLastWriteTimeUtc()
检查文件的文件修改时间戳,并且仅当时间戳比上次检查的时间戳新时才打开文件进行读取。这将避免不必要地打开文件,减少文件锁定冲突的可能性FileSystemWatcher
为您完成工作,并且仅在引发Changed
事件时读取文件。这样做的主要缺点是,FileSystemWatcher
并不总是(事实上,通常不是)及时通知文件的更改。它最终会引发相应的事件,但它跟踪的目录信息本身并不总是由Windows及时更新的,这会导致在收到更改通知时出现延迟(根据我的经验,最多几十秒)如果您可以接受在收到通知前最多一分钟的延迟,那么我建议
FileSystemWatcher
。否则,只需每秒轮询一次(或不太频繁),或者使用#1选项(至少检查修改时间戳)就可以了。不确定循环是否导致了此问题。你能利用Hi@qxg吗?谢谢你的评论。在实际环境中,文本文件中的值将是配置应用程序(连接到配置服务器)中的值,我可以从配置应用程序中检索该值,但一旦该值发生更改,就无法更新应用程序中的值。对于上面的问题,我只给出了一个与实际问题类似的简单示例。您的代码对我很有用。检查其他问题。在我运行我的应用程序后,该值不断循环,当我更改文本文件中的值时,它不允许我保存,因为该文件被其他程序使用。这只是文件系统问题?所以问题不在于如何实现INotifyPropertyChanged
(当然,通过比较TestValue
属性中的旧值来检查值是否真的发生了更改)。您在如何从其他应用程序/服务器读取值方面遇到问题。如果可能,请更新问题。不确定循环是否导致此问题。你能利用Hi@qxg吗?谢谢你的评论。在实际环境中,文本文件中的值将是配置应用程序(连接到配置服务器)中的值,