Reputation: 1063
I have created an application that will watch a certain folder for only newly created files and list it in the listbox, now I want to do is everytime it will detect the file the application will read it and display the text on it in the listbox, I almost got because sometimes when it detects 2 or 3,4,5,6 etc files sometimes ok but sometimes also it will prompt error "The process cannot access the file 'C:\Users\PHWS13\Desktop\7.request.xml' because it is being used by another process.".
How to fix this? Here is my code:
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());
}
});
Upvotes: 6
Views: 2692
Reputation: 1998
Try using XDocument.Load(Stream)
with read-only options:
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
var doc = XDocument.Load(stream);
// ...
}
Upvotes: 4
Reputation: 5551
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.
Upvotes: 2