【问题标题】:File is being used by another process with FileSystemWatcher and TaskFileSystemWatcher 和 Task 正在被另一个进程使用文件
【发布时间】:2012-11-23 10:47:35
【问题描述】:

我创建了一个应用程序,它将仅监视某个文件夹中新创建的文件并将其列出在列表框中,现在我想做的是每次它会检测到应用程序将读取它并在其中显示文本的文件列表框,我几乎得到了,因为有时当它检测到 2 或 3、4、5、6 等文件时有时可以,但有时也会提示错误“进程无法访问文件'C:\Users\PHWS13\Desktop\7. request.xml',因为它正被另一个进程使用。”。

如何解决这个问题?这是我的代码:

private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
    {
        if (!listBox1.Items.Contains(e.FullPath))
        {
            //add path
            listBox1.Items.Add(e.FullPath + "" + DateTime.Now.ToString());
            //get the path
            path = e.FullPath;
            //start task
            startTask();
        }
    }

    private void startTask()
    {
        //start task
        Task t = Task.Factory.StartNew(runThis);
    }

    private void runThis()
    {
        //get the path
        string get_the_path = path;

        XDocument doc = XDocument.Load(get_the_path);
        var transac = from r in doc.Descendants("Transaction")
                      select new {
                          InvoiceNumber = r.Element("InvoiceNumber").Value,
                      };
        listBox2.Invoke((MethodInvoker)delegate() { 
            foreach(var r in transac){
                listBox2.Items.Add(r.ToString());
            }
        });

【问题讨论】:

    标签: c# multithreading task filesystemwatcher


    【解决方案1】:

    尝试使用带有只读选项的XDocument.Load(Stream)

    using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read)) 
    {
        var doc = XDocument.Load(stream);
    
        // ...
    }
    

    【讨论】:

    • 嘿,解决了,我刚刚添加了这个“FileShare.ReadWrite”
    【解决方案2】:

    您在没有锁定的情况下共享所有任务的路径变量。这意味着您的所有任务都可能试图同时访问同一个文件。您应该将路径作为变量传递给 startTask():

    private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
    {
        if (!listBox1.Items.Contains(e.FullPath))
        {
            //add path
            listBox1.Items.Add(e.FullPath + "" + DateTime.Now.ToString());
    
            //start task
            startTask(e.FullPath);
        }
    }
    
    private void startTask(string path)
    {
        //start task
        Task t = Task.Factory.StartNew(() => runThis(path));
    }
    
    private void runThis(string path){}
    

    编辑: 此线程:Is there a way to check if a file is in use? 对文件访问进行了简单而丑陋的检查,您可以尝试测试文件,如果失败则跳过文件或等待重试。

    【讨论】:

    • 另一个用于创建文件的应用程序。也可能是不止一台计算机会使用该应用程序
    • 无法直接运行,无需等待。并且在创建文件时是唯一的:)
    • 如果不是您自己的任务在争夺文件,那么它必须是创建它的应用程序。您可能会在创建者完成编写文件之前获取该文件。如果您等待一秒钟(或更少),它可能会变得空闲,因此您可以抓住它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    相关资源
    最近更新 更多