【问题标题】:The process cannot access the file because it is being used by another process. (threads)该进程无法访问该文件,因为它正被另一个进程使用。 (线程)
【发布时间】:2010-08-12 21:30:32
【问题描述】:

我使用单独的线程将调试信息写入文件。在启动期间,我喜欢备份任何以前的文件。不幸的是,似乎操作系统挂在文件句柄上的时间不确定,所以当我尝试写入文件时,它失败了。

我在 Windows XP 上使用 C#、.Net framework 3.5。 (Vista和Win7有同样的问题)。

这里是提取问题的代码,t 将抛出 System.IO.IOException:“进程无法访问文件 'C:\deleteMe.txt',因为它正被另一个进程使用。”

public class WriteToFile {

    static void Main(){
        String filename=@"C:\deleteMe.txt";
        String filenameBackup = @"C:\deleteMe (backup).txt";
        String value = "this is a test value";

        //MAKE FILE
        fillFile(filename, value);


        //MAKE A THREAD TO WRITE TO FILE, WHEN READY
        Semaphore readyToWrite=new Semaphore(1, 1);
        var t=new Thread(
            new ThreadStart(delegate(){
                readyToWrite.WaitOne();
                WriteToFile.fillFile(filename, value);
            })
        );
        t.Priority=ThreadPriority.Highest;
        t.Start();


        //BACKUP FILE 
        if (File.Exists(filename)) {
            File.Delete(filenameBackup);
            File.Copy(filename, filenameBackup);
            File.Delete(filename);
        }//endif

        //SIGNAL THREAD TO WRITE TO FILE
        readyToWrite.Release();
    }//method


    public static void fillFile(String filename, String value) {
        try {
            StreamWriter w = File.AppendText(filename);
            using (w) {
                w.Write(value);
                w.Flush();
            }//using
        } catch (Exception e) {
            throw new Exception("Can not write to file", e);
        }//try
    }//method


}//class

谢谢!

【问题讨论】:

  • 写入文件时是否正确关闭或处理文件?
  • @Steven:这就是所提供的代码中的全部内容。答案是肯定的。
  • @Henk:原来可以向下滚动! :-) 好的,wusing 之前的声明有点奇怪,但应该是无害的,对Flush 的调用也应该如此。据我所知,没有理由不应该立即使用该文件。可能还涉及到其他一些过程,例如防病毒扫描程序。
  • @Steven:向下滚动一些,我的答案。问题已经解决了。
  • 实际的复制顺序也有点奇怪。 Exists 是多余的,我不确定它为什么会出现 CopyDelete 而不仅仅是 Move。同样,这些都不能解释文件被锁定的原因。

标签: c# .net file-io


【解决方案1】:

您正在初始化信号量错误。试试看:new Semaphore(0, 1);

this MSDN page

WaitEvent 可能更容易且更适合此任务。

两个代码更改是:

//Semaphore readyToWrite=new Semaphore(1, 1);
var readyToWrite = new ManualResetEvent(false);

//readyToWrite.Release();
readyToWrite.Set();

此外,设置优先级通常不是一个好主意。你不会在这里得到任何东西(它是一个 I/O 线程),所以最好离开它。

【讨论】:

  • +1,是的。启动一个线程,然后等待它也是一种资源浪费。设置更高的优先级并不意味着购买更快的硬盘。
  • @Hans:同意优先级,我会补充。对于其余部分,我认为这是一个摘录,所以我不确定它是否是一个糟糕的设计。
  • 谢谢,我想这很简单。我的蒸馏代码有一个错误,数字。
猜你喜欢
  • 2010-12-10
相关资源
最近更新 更多