我围绕FileSystemWatcher
创建了一个包装器类。该类的目的是等待创建文本文件,然后将其内容读取到其_result
字段中。
我想在名为GetResultAsync()
的类中添加一个方法,以便调用者可以await
来准备好结果,但是我不知道该怎么做。请有人指出我正确的方向吗?
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();
}
}
答案 0 :(得分:0)
扩展Jeroen Mosterts评论。您的代码应如下所示:
internal Task<string> GetResultAsync()
{
var tcs = new TaskCompletionSource<string>();
ProcessFile();
tcs.TrySetResult(_result);
return tcs.Task;
}
这非常幼稚,我建议您考虑一下带有异常处理和取消的方案。它们应位于ProcessFile
内,使其看起来像Task<string> ProcessFile(TaskCompletionSource<string> tcs)
。
要设置例外,请使用tcs.TrySetException(exception)
。