我该如何修复“进程无法访问该文件,因为它正被另一个进程使用”错误

时间:2012-04-07 16:48:06

标签: multithreading c#-4.0 file-io parallel-processing

如下所示,我有Parallel.For循环。如果在文件不存在的情况下运行程序,则会出现类似&#34的错误;进程无法访问文件' C:\ ShowTime错误日志\ logFile.txt'因为它正被另一个进程使用。"

但是如果文件存在则没有错误。我很困惑,我的代码已经创建了文件,即使文件不存在也是如此。如果在运行程序之前文件不存在,为什么它会给我一个错误。我该如何解决?

THX

ErrorLog el = new ErrorLog();
        Parallel.For(0, 100000, delegate(int i)
    {
        el.WriteToShowTimeLog("logFile", "", "", (i).ToString(), "", "", @"C:\");
    });

ErrorLog类有一个函数和静态变量

private static readonly object lock_ = new object();
    public  void WriteToShowTimeLog(string fileName, string errorMessage, string description, string movieID, string theaterID, string showTimeDate, string folderPath)
    {
        string filePath = folderPath + @"\ShowTime Error Logs\" + fileName + ".txt";
        lock (lock_)
        {

            if (!Directory.Exists(folderPath + @"\ShowTime Error Logs"))
            {
                Directory.CreateDirectory(folderPath + @"\ShowTime Error Logs");
            }

            if (!File.Exists(filePath))
            {
                File.Create(filePath);
            }

            using (StreamWriter dosya = new StreamWriter(filePath,true))
            {

                dosya.WriteLine("TheaterID:        " + theaterID);
                dosya.WriteLine("MovieID:          " + movieID);
                dosya.WriteLine("Show Time Date:   " + showTimeDate);
                dosya.WriteLine("Hata Mesajı:      " + errorMessage);
                dosya.WriteLine("Açıklama:         " + description);
                dosya.WriteLine("Hata Alınan Zaman:" + DateTime.Now);
                dosya.WriteLine("-------------------------------------------------------------------------------------------------------");
                dosya.Close();


            }
        }
    }

2 个答案:

答案 0 :(得分:2)

您需要在锁中包含文件检查和创建,否则您可以同时从两个单独的线程创建它,从而产生您看到的错误。

修改

File.Create返回一个打开的文件。然后StreamWriter尝试再次打开它。您可能应该为简化设置选项,而不是尝试创建它,然后为StreamWriter重新创建它。

答案 1 :(得分:1)

锁之外的任何东西都可以由任何线程以任何顺序运行。不要做出相反的假设。在这种情况下,您可能会检查线程#1是否存在该文件。因为它没有,它进入if子句并且线程#2接管。线程#2检查文件是否存在。因为它没有,所以线程#2进入if子句并创建文件。一旦线程#1再次接管,就会惊喜!文件已经创建,即使它“只是”检查它不存在。

大多数输出​​流将自动创建具有数据的文件,因此甚至可能不需要具有该部分。