C#等待外部应用程序关闭文件

C#等待外部应用程序关闭文件,c#,filesystemwatcher,C#,Filesystemwatcher,当已知文件已被外部应用程序关闭时,是否有可以捕获的事件 例如,用户正在Excel中编辑工作簿,我希望在用户完成工作并关闭该文件后立即读取该文件 我目前的解决方案是结合使用FileSystemWatcher和Timer。FileSystemWatcher将检测文件何时发生更改,并启动一个新线程,运行计时器检查文件何时关闭(通过),但我觉得这不是一个好的解决方案。如果用户忘记关闭文件并在周末回家,我的计时器会一直运行,这会让人觉得浪费时间。如果我增加定时器的时间间隔,那么我的程序就不会有那么高的响应

当已知文件已被外部应用程序关闭时,是否有可以捕获的事件

例如,用户正在Excel中编辑工作簿,我希望在用户完成工作并关闭该文件后立即读取该文件

我目前的解决方案是结合使用FileSystemWatcher和Timer。FileSystemWatcher将检测文件何时发生更改,并启动一个新线程,运行计时器检查文件何时关闭(通过),但我觉得这不是一个好的解决方案。如果用户忘记关闭文件并在周末回家,我的计时器会一直运行,这会让人觉得浪费时间。如果我增加定时器的时间间隔,那么我的程序就不会有那么高的响应速度。有没有一个不涉及投票的解决方案

编辑:用我拥有的代码示例更新

    private System.Windows.Forms.Timer processTimer;
    private string blockedFile;

    // Starts here. File changes were detected.
    private void OnFileSystemWatcher_Changed(object source, FileSystemEventArgs e)
    {
        FileSystemWatcher fsw = (FileSystemWatcher)source;
        string fullpath = Path.Combine(fsw.Path, fsw.Filter);
        StartFileProcessing(fullpath);
    }

    private void StartFileProcessing(string filePath)
    {
        if (isFileOpen(new FileInfo(filePath)))
        {
            blockedFile = filePath;
            processTimer = new System.Windows.Forms.Timer();
            processTimer.Interval = 1000; // 1 sec
            processTimer.Tick += new EventHandler(processTimer_Elapsed);
            processTimer.Enabled = true;
            processTimer.Start(); 
        }
        else
            ProcessFile(filePath);

    }

    private void ProcessFile(string filePath)
    {
        // Do stuff, read + writes to the file.
    }

    // GOAL: Without polling, how can I get rid of this step just know right away when the file has been closed?
    private void processTimer_Elapsed(object sender, EventArgs e)
    {
        if (isFileOpen(new FileInfo(blockedFile)) == false)
        {
            // The file has been freed up
            processTimer.Enabled = false;
            processTimer.Stop();
            processTimer.Dispose();

            ProcessFile(blockedFile);
        }
    }

    // Returns true if the file is opened
    public bool isFileOpen(FileInfo file)
    {
        FileStream str = null;
        try
        {
            str = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
        }
        catch (IOException)
        {
            return true;
        }
        finally
        {
            if (str != null)
                str.Close();
        }
        return false;
    }

您可以侦听FileSystemWatcher的已更改事件,这样您就不必使用计时器进行检查。它表示“当对被监视目录中的文件或目录的大小、系统属性、上次写入时间、上次访问时间或安全权限进行更改时,会引发更改事件。”进一步的详细信息。虽然我不确定是否需要知道文件是否已关闭。您的计划必须知道它是否已关闭吗?看看这是否有助于感谢您的回复PM&Tony@PM:是的,我需要知道文件是否关闭,因为我需要回写它。@托尼:我来看看。根据我的经验,虽然您的具体示例还可以,但更一般的情况是,这通常是由于在释放锁时出现问题造成的,您需要等待很长时间。根据触发第一个文件更改通知的原因,本文可能会很有用