C# 关闭StreamWriter后解析正在使用的异常文件

C# 关闭StreamWriter后解析正在使用的异常文件,c#,exception,streamwriter,file-in-use,C#,Exception,Streamwriter,File In Use,我得到一个错误: The process cannot access the file 'C:\AMR_VOYANT_TESTING\PWM_TESTER\UUT_LOGS\TEST_LOG_PWM_10245_UUT_SN_10.TXT' because it is being used by another process. 我的程序刷新、关闭和处理日志文件。我的程序稍后会尝试打开该文件以附加更多数据。第二次打开导致上述异常 在直接访问二进制文件或使用MS Visual C Expres

我得到一个错误:

The process cannot access the file 
'C:\AMR_VOYANT_TESTING\PWM_TESTER\UUT_LOGS\TEST_LOG_PWM_10245_UUT_SN_10.TXT'
because it is being used by another process.
我的程序刷新、关闭和处理日志文件。我的程序稍后会尝试打开该文件以附加更多数据。第二次打开导致上述异常

在直接访问二进制文件或使用MS Visual C Express 2008在调试模式下运行的执行过程中,Process Explorer不显示文件的句柄

其他进程不应使用此文件,因为它是由我的应用程序创建的原始文件

堆栈溢出中的一些解决方案建议实现using语句,但这是不可行的,因为数据写入不会发生在简单或简短的复合语句中。日志类使用writer委托将数据写入文件

根据堆栈溢出中的其他解决方案,在for循环中,在打开文件的下一次迭代之前,可能不会关闭文件。在再次打开文件之前,我已经等了超过10秒钟,但同样的例外情况也没有发生

以下是代码示例:

    public void
    close()
    {
        get_log_file().WriteLine("");
        get_log_file().Flush();
        get_log_file().Close();
        get_log_file().Dispose();
        m_log_file = null;
        return;
    }


    private StreamWriter
    get_log_file()
    {
        if (m_log_file == null)
        {
            bool successful = false;
            int retries_remaining = 5;
//                do
//                {
//                    try
//                    {            
//                        m_log_file = new StreamWriter(m_filename, true);
                m_log_file = new StreamWriter(new FileStream(m_filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None));
//                    }
//                    catch (IOException)
//                    {

//                        --retries_remaining;
//                        System.Threading.Thread.Sleep(250); // Units are in milliseconds;
//                    }
//                } while (!successful && (retries_remaining >= 0));
            }
            return m_log_file;
        }
        private System.IO.StreamWriter m_log_file = null;
        private string m_filename;
因为我有一个最后期限,我正在寻找解决这个问题的办法。我的一些想法是:

保持档案开放;不要打开和关闭 在测试运行期间。 显示等待文件消息 在将文件轮询到时发送给用户 看看什么时候可以再次打开 编写非托管C或C++ 用于处理文件I/O的库 由于非托管C和C++不使用 NET框架。 学习如何告诉.NET 框架,以加快并关闭 文件 我正在Windows 7上使用MS Visual C 2008 Express,64位体系结构

如果你想把它做好,你必须花一些时间。或 使用一个或框架。 我猜您正在调试VisualStudio宿主进程。尝试禁用它并检查文件锁定问题是否消失。 禁用的复选框

Project - Properties - Debug - x Enable Visual Studio hosting process
也可能是在应用程序关闭期间,StreaWriter已经关闭,您正在跟踪其中一个终结器。你可以通过使用

你的,
Alois Kraus

我希望能为您提供一个快速的解决方案,就是用FileMode.Append替换FileMode.open或create

正如其他人指出的那样,还有无数其他日志记录选项,但我相信这可能会为您提供一条快速前进的道路,而不是倒退前进


在我看来,您的代码是将streamwriter返回到调用上下文的类的片段。我会让您的类实现IDisposable将您的close to Dispose更改为implement IDisposable,然后让您的使用者使用yourLogClass logger=new yourLogClass将调用包装到一个文件中。。。等,以确保每次使用时都会调用close。

调用此类中方法的代码在调用open方法后不会调用close方法。根据您发布的代码,我假设有一个单独的open方法。如果该方法被多次调用,那么您将得到所描述的异常。您发布的代码没有任何问题会导致出现异常。如果在调用Close之前调用Flush,它将强制写入磁盘,这样在调用Close时就不会有延迟。我在一两秒内打开和关闭了数百次文件,从未遇到过这个问题


更新:如果您的代码在调试时引发了异常,VS仍然在该文件上有一个打开的句柄。即使您已经更正了代码,它也会继续抛出该异常。我通常只是关闭并重新启动VS,以免弄乱我的项目设置,并意外地将它们签入源代码管理。

我通过保持文件处于打开状态来解决此问题,从而消除了每次重新打开文件的需要。

为什么要编写自己的日志?你能用log4net这样的框架来写这个日志吗?因为我可以很快给你答案。你能把FileShare.None改成FileShare.ReadWrite吗?如果不使用“using”,你应该使用always,并尝试最后确保总是调用Dispose。第一个测试可能会在刷新和处置之间失败?如果我们相信您的代码段,那么您有一个名为close的方法正在打开日志文件。没有多大意义,您的代码只是不调用close。真正的代码可能也不是异常安全的。NullReferenceException是通过不检查get_log_文件的返回值而允许的另一种故障模式。是否确实在收到错误时ProcExp未显示任何打开文件的句柄?您应该发布一个复制问题的最小工作示例。此外,该类保留了一个非托管资源,计算机上的非托管资源数量有限。您需要实现IDisposable和终结器。