我需要阅读快速增长的测试文件,并尽快处理任何新行。 该文件可以每毫秒更新几次。
如果我在“PROBLEM”代码行中引入睡眠(如下所示),它可以很好地工作,但会引入1毫秒的延迟。
如果我注释掉“问题”行,我没有延迟,但我的CPU使用率达到了70%。
有更好的方法可以解决这个问题吗?
public void UpdatePricesFromSFile()
{
using (txtFileReader = new StreamReader(File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
{
txtFileReader.BaseStream.Seek(0, SeekOrigin.End);
while (true)
{
while ((line = txtFileReader.ReadLine()) == null)
{
System.Threading.Thread.Sleep(1); //PROBLEM
}
//Process line
}
}
}
答案 0 :(得分:0)
使用代码示例扩展我的评论:
public abstract class FileWatcher
{
// last known position of the stream
int m_LastStreamPosition;
// flag to check if file is currently in read state
volatile bool m_IsReading;
// info about the file
FileInfo m_FileInfo;
// file system watcher
FileSystemWatcher m_Watcher;
// standard ctor used to watch specific file
public FileWatcher(string filePath)
{
// create new instance of FileSystem using the path of the file
m_FileInfo = new FileInfo(filePath);
// if ( !m_FileInfo.Exists ) throw new InvalidArgumentException("filePath");
// start watcher based on the FileInfo
m_Watcher = new FileSystemWatcher(m_FileInfo.DirectoryName, m_FileInfo.Extension);
m_Watcher.EnableRaisingEvents = true;
m_Watcher.Changed += WhenFileChanged;
// reset stream position and read file initialy
m_LastStreamPosition = 0;
ReadFile();
}
// event fired when file is changed
// !! note that this will fire whenever you create file in the same
// directory as your desired file is and with the same extension
// and then change/modify this file
void WhenFileChanged(object source, FileSystemEventArgs e)
{
// based on the note comment, check if that's our desired file
if ( e.FullPath != m_FileInfo.FullName ) return;
// refresh informations about the file
m_FileInfo.Refresh();
// check if something was added to the file,
// in case something was removed (?) reset lastStreamPosition (?)
if ( m_FileInfo.Length <= m_LastStreamPosition )
m_LastStreamPosition = 0;
// read the file
ReadFile();
}
void ReadFile()
{
if ( m_IsReading ) return;
m_IsReading = true;
using ( StreamReader reader = m_FileInfo.OpenText() )
{
reader.BaseStream.Position = m_LastStreamPosition;
string line = string.Empty;
while ( ( line = reader.ReadLine() ) != null )
{
ProcessLine(line);
}
m_LastStreamPosition = reader.BaseStream.Position;
}
m_IsReading = false;
}
protected abstract void ProcessLine(string line);
}
样本用法:
public class MeFileWatcher
: FileWatcher
{
public MeFileWatcher(string filePath)
: base(filePath)
{
}
protected override void ProcessLine(string line)
{
Console.WriteLine ("NEW LINE ADDED -> {0}", line);
}
}
MeFileWatcher meFileWatcher = new MeFileWatcher("D:\\testData\\meFile.txt");