I've created a wrapper class around a FileSystemWatcher
. The purpose of the class is to wait for a text file to be created and then read the file's contents into its _result
field.
I would like to add a method to the class called GetResultAsync()
so the caller can await
for the result to be ready, but I don't know how best to go about it. Please would someone point me in the right direction?
internal class SingleFileWatcher : IDisposable
{
private readonly string _targetFile;
private readonly FileSystemWatcher _fileWatcher;
private string _result = null;
internal SingleFileWatcher(string theFile)
{
_targetFile = theFile;
_fileWatcher = new FileSystemWatcher();
_fileWatcher.Path = Path.GetDirectoryName(theFile);
_fileWatcher.Filter = Path.GetFileName(theFile);
_fileWatcher.IncludeSubdirectories = false;
_fileWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName;
_fileWatcher.Created += FileCreated;
if (File.Exists(theFile))
{
ProcessFile();
}
else
{
//this must happen after other members have been set
_fileWatcher.EnableRaisingEvents = true;
}
}
internal Task<string> GetResultAsync()
{
//todo
}
private void FileCreated(Object sender, FileSystemEventArgs e)
{
ProcessFile();
}
private void ProcessFile()
{
FileStream stream = null;
//filecreated is raised as soon as the file is created, but the process may still be writing to the file
while (true)
{
try
{
stream = new FileStream(_targetFile, FileMode.Open, FileAccess.Read);
using (var reader = new StreamReader(stream))
{
stream = null;
_result = reader.ReadToEnd();
}
break;
}
catch (IOException)
{
Thread.Sleep(TimeSpan.FromMilliseconds(500));
}
finally
{
stream?.Dispose();
}
}
}
public void Dispose()
{
_fileWatcher.Created -= FileCreated;
_fileWatcher.Dispose();
}
}