【发布时间】:2011-01-07 08:17:25
【问题描述】:
我有一个小问题。我的应用程序应该做的是观察一个文件夹,以查看任何带有扩展名“.XSD”的新复制文件,打开文件并将这些行分配给一个数组。之后,数组中的数据应该被插入到 MySQL 数据库中,如果完成,则将使用的文件移动到另一个文件夹。
问题是应用程序在第一个文件上运行良好,但是一旦将下一个文件复制到文件夹中,我就会收到此异常,例如:'进程无法访问文件'C:\inetpub\admission\ file2.XPD',因为它正被另一个进程使用'。
如果同时复制两个文件,则完全没有问题。
以下代码在主窗口中:
public partial class Form1 : Form
{
static string folder = specified path;
static FileProcessor processor;
public Form1()
{
InitializeComponent();
processor = new FileProcessor();
InitializeWatcher();
}
static FileSystemWatcher watcher;
static void InitializeWatcher()
{
watcher = new FileSystemWatcher();
watcher.Path = folder;
watcher.Created += new FileSystemEventHandler(watcher_Created);
watcher.EnableRaisingEvents = true;
watcher.Filter = "*.XPD";
}
static void watcher_Created(object sender, FileSystemEventArgs e)
{
processor.QueueInput(e.FullPath);
}
}
如您所见,文件的路径被输入到另一个名为 FileProcessor 的类上的处理队列中:
class FileProcessor
{
private Queue<string> workQueue;
private Thread workerThread;
private EventWaitHandle waitHandle;
public FileProcessor()
{
workQueue = new Queue<string>();
waitHandle = new AutoResetEvent(true);
}
public void QueueInput(string filepath)
{
workQueue.Enqueue(filepath);
if (workerThread == null)
{
workerThread = new Thread(new ThreadStart(Work));
workerThread.Start();
}
else if (workerThread.ThreadState == ThreadState.WaitSleepJoin)
{
waitHandle.Set();
}
}
private void Work()
{
while (true)
{
string filepath = RetrieveFile();
if (filepath != null)
ProcessFile(filepath);
else
waitHandle.WaitOne();
}
}
private string RetrieveFile()
{
if (workQueue.Count > 0)
return workQueue.Dequeue();
else
return null;
}
private void ProcessFile(string filepath)
{
string xName = Path.GetFileName(filepath);
string fName = Path.GetFileNameWithoutExtension(filepath);
string gfolder = specified path;
bool fileInUse = true;
string line;
string[] itemArray = null;
int i = 0;
#region Declare Db variables
//variables for each field of the database is created here
#endregion
#region Populate array
while (fileInUse == true)
{
FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read,
FileShare.ReadWrite);
StreamReader reader = new StreamReader(fs);
itemArray = new string[75];
while (!reader.EndOfStream == true)
{
line = reader.ReadLine();
itemArray[i] = line;
i++;
}
fs.Flush();
reader.Close();
reader.Dispose();
i = 0;
fileInUse = false;
}
#endregion
#region Assign Db variables
//here all the variables get there values from the array
#endregion
#region MySql Connection
//here the connection to mysql is made and the variables are inserted into the db
#endregion
#region Test and Move file
if (System.IO.File.Exists(gfolder + xName))
{
System.IO.File.Delete(gfolder + xName);
}
Directory.Move(filepath, gfolder + xName);
#endregion
}
}
我遇到的问题发生在填充数组区域中。我阅读了很多其他线程,并被引导相信通过刷新文件流会有所帮助......
我也在考虑添加一个 try..catch,如果文件处理成功,文件将移动到 gfolder,如果失败,则移动到 bfolder
任何帮助都会很棒
发送
【问题讨论】:
-
看起来像是某种竞争条件。当 VS 在异常上中断时,检查 View->Debug->Threads 并查看是否还有另一个文件仍在使用中。编辑:另外,FileStream 没有被释放,尝试把它放在 using {...}
-
并不是说我不知道问题出在哪里,只是为了向其他人澄清:你什么时候得到异常?什么时候使用阅读器?
-
不确定 while (fileInUse == true) 语句。在此处尝试使用 using(FileStream fs = FileStream(...)) 语句。