c# - 调试时读取字符串或正常运行时出现 NullReferenceException

标签 c#

<分区>

TestProgram_Load() 方法中调用 DoSomething();(来自 Something();)时尝试读取文件时,我遇到了 NullReferenceException,我无法理解它。

当试图检查文件是否存在,甚至试图读取它时,就会发生这种情况。但是,即使在调试器中,我也可以毫无问题地写入文件,引用字符串值。

问题代码如下:

// No matter the file name, this fails every time.
string fileName = "file.txt";

public void DoSomething()
{
    if (File.Exists(fileName)) // NullReferenceException
    {
        using (StreamReader r = new StreamReader(fileName)) // NullReferenceException
        {

        }
    }
}

以及调用它的方法:

public void Something()
{
    // This works fine
    if (!File.Exists(fileName))
    {
        // This works fine
        using (StreamWriter w = new StreamWriter(fileName))
        {
             w.Write("Test");
        }
    }

   // Test to see if there's an issue with this method too...
   // This is fine, but whether or not File.Exists(fileName) is used, DoSomething(); has the same problem.

   if (File.Exists(fileName))
   { 
       DoSomething(); 
   }

}

这是 TestProgram_Load 方法:

private void TestProgram_Load(object sender, EventArgs e)
{
    TestClass t = new TestClass();
    t.Something();
}

这是堆栈跟踪:

at TestProgram.TestClass.DoSomething() in Visual Studio 2015\Projects\Test Program\Test Program\Classes\FileSystem\TestClass.cs:line 39
at TestProgram.Program.Main() in Visual Studio 2015\Projects\Test Program\Test Program\Program.cs:line 19
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

第 39 行:

if (File.Exists(fileName))

此代码在主程序的启动函数中执行:在构造函数或 TestProgram_Load() 方法中执行:两者都有相同的问题。根本不应该有任何线程。

以下是一些关键细节:

  1. 我尝试读取文件 DoSomething();
  2. 字符串值存在于调试器中,可以在 File.Exists(fileName) 之前引用
  3. File.Exists(fileName) 以不同的方法工作,但不是这个。
  4. 字符串根本没有更新
  5. 字符串值是硬编码的。
  6. 没有其他线程会干扰它。

我希望它能实际检测到文件的存在,当然,还能打开文件。这是怎么回事?

最佳答案

有趣的是 documentation for File.Exists状态:

The Exists method returns false if any error occurs while trying to determine if the specified file exists. This can occur in situations that raise exceptions such as passing a file name with invalid characters or too many characters, a failing or missing disk, or if the caller does not have permission to read the file.

我最初的倾向是相信在您尝试读取时写入仍在完成,但根据文档,这应该仍然只是返回 false。这听起来像是一个内部 .Net 错误。

我没有明确的答案,但您可以通过以下方式找到根本原因:

  • 在写入 1000 毫秒后放置一个 Thread.Sleep
  • 使用 FileInfo 而不是 File(以防 File 中存在错误
  • 不要检查 File.Exists 并查看您的流是否给您带来更具描述性的错误

如果这些不起作用,并且您知道该字符串第一次起作用,您可以尝试完全切换到使用 FileInfo 类。像这样的东西:

var file = new FileInfo(fileName);
if (!file.Exists())
{
    using (var writer = file.CreateText())
    {
        writer.Write("test");
    }
}
using (var writer = file.OpenText())
{
    // do stuff
}

请原谅我的代码,如果它没有构建。我没有在此设备上安装 visual studio。

关于c# - 调试时读取字符串或正常运行时出现 NullReferenceException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38486959/

相关文章:

c# 依赖注入(inject)与接口(interface)和隐藏内部

c# - 如何从 Reflection 中的 ParameterInfo[] 获取实际值

C# 手机游戏开发

c# - 如何构建 Windows 窗体电子邮件感知文本框?

c# - 声明数据库变量的良好做法

c# - Azure 表存储错误地插入日期属性

c# - 如何将 ASP.NET Core 应用程序和 Redis 一起 dockerize?

c# - c# win apps 中的用户控制和数据绑定(bind)

c# - 使用动态 LINQ 展平一对多关系

c# - DataSet Select 不加起来