FileSystemWatcher和Task:文件正在被另一个进程使用

6
我创建了一个应用程序,它会监视特定文件夹中仅新建的文件并在列表框中列出它们。现在我想做的是每次检测到文件时,应用程序都会读取它并在列表框中显示其文本。我几乎成功了,因为有时当它检测到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());
            }
        });
2个回答

4
尝试使用只读选项的XDocument.Load(Stream)
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read)) 
{
    var doc = XDocument.Load(stream);

    // ...
}

嘿,问题已经解决了,我刚刚添加了这个 "FileShare.ReadWrite"。 - GrayFullBuster

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){}

编辑: 这个线程:有没有一种方法可以检查文件是否正在使用?有一个简单而丑陋的文件访问检查,您可以尝试使用它来测试文件,如果失败,则跳过该文件或等待并再次尝试。


另一个创建文件的应用程序。它还可能是多台计算机将使用该应用程序。 - GrayFullBuster
无法直接运行,无需等待。文件的创建是独特的 :) - GrayFullBuster
1
如果不是你自己的任务在争夺文件,那么就一定是正在创建它的应用程序。有可能你会在创建者写完之前就拿到了这个文件。如果你等待一秒钟(或更短时间),它很可能就会变成空闲状态,这时你就可以获取它了。 - Mike Parkhill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接