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

时间:2017-02-13 22:02:59

标签: c# filesystemwatcher

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

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

我目前的解决方案是使用FileSystemWatcher和Timer的组合。 FileSystemWatcher将检测何时对文件进行了更改,并启动一个运行Timer的新线程来检查文件何时关闭(通过try-catch)但是我觉得这不是很好解。如果用户忘记关闭文件并回家度周末,那​​么我的Timer一直在运行会感到浪费。如果我增加我的计时器的间隔,那么我的程序将不会像响应一样。有没有涉及民意调查的解决方案?

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

    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;
    }

0 个答案:

没有答案