【问题标题】:Awaitable FileSystemWatcher Result [duplicate]等待的 FileSystemWatcher 结果 [重复]
【发布时间】:2018-10-16 22:07:15
【问题描述】:

我围绕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();
    }
}

【问题讨论】:

  • TaskCompletionSource 可能是你的朋友。
  • 谢谢,TaskCompletionSource 为我解决了这个问题。

标签: c#


【解决方案1】:

扩展 Jeroen Mosterts 的评论。您的代码应如下所示:

internal Task<string> GetResultAsync()
{
    var tcs = new TaskCompletionSource<string>();
    ProcessFile();
    tcs.TrySetResult(_result);
    return tcs.Task;
}

这很幼稚,我建议您考虑异常处理和取消的场景。它们应该在ProcessFile 内,所以它看起来像Task&lt;string&gt; ProcessFile(TaskCompletionSource&lt;string&gt; tcs)。 设置异常使用tcs.TrySetException(exception)

【讨论】:

    猜你喜欢
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 2021-04-29
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多