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());
            }
        });
4

2 回答 2

4

Try using XDocument.Load(Stream) with read-only options:

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

    // ...
}
于 2012-11-23T02:47:35.507 回答
2

You're sharing the path variable on all the tasks without locking. This means all your tasks could be trying to access the same file at the same time. You should be passing the path as a variable to 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){}

EDIT: This thread: Is there a way to check if a file is in use? has a simple and ugly check for file access you could try that to test the file, if it fails then skip the file or wait and try again.

于 2012-11-23T02:03:58.737 回答