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

C# 调试时读取字符串或正常运行时出现NullReferenceException,c#,C#,调用DoSomething()时尝试读取文件时(来自Something();)在TestProgram\u Load()方法中,我遇到了一个NullReferenceException,我很难理解它 当试图检查文件是否存在,甚至试图读取文件时,都会发生这种情况。但是,即使在调试器中,我也能够毫无问题地写入文件并引用字符串值 以下是问题代码: // No matter the file name, this fails every time. string fileName = "file.txt

调用
DoSomething()时尝试读取文件时
(来自
Something();
)在
TestProgram\u Load()
方法中,我遇到了一个
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_加载方法:

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\u Load()
方法中:两者都有相同的问题。根本不应该有任何线程

以下是一些关键细节:

  • 我试图读取文件,
    DoSomething()
  • 该字符串值存在于调试器中,可以在
    File.exists(fileName)
  • File.Exists(fileName)
    使用另一种方法,但不是此方法
  • 字符串根本没有被更新
  • 字符串值是硬编码的
  • 没有其他线程对此进行干扰
  • 我想让它实际检测存在,当然,打开文件。这里发生了什么事?

    确保你有

    using System.IO;
    
    什么是运行时上下文?这是IIS托管环境还是windows执行环境

    在web托管环境中,您需要执行以下操作:

    var physicalFolder = HostingEnvironment.MapPath(VirtualFolder);
    if (File.Exists(physicalFolder + fileName)){
        ...
    }
    
    在windows运行时上下文中,您需要:

    var rootOfCurrentPath = Path.GetPathRoot(Environment.CurrentDirectory);
    if (File.Exists(rootOfCurrentPath + fileName)){
        ...
    }
    

    有趣的是,美国:

    如果在尝试执行时发生任何错误,Exists方法将返回
    false
    确定指定的文件是否存在。这可能发生在某些情况下 引发异常,例如传递带有无效字符的文件名 字符或字符太多,磁盘出现故障或丢失,或者 调用方没有读取文件的权限

    我最初的倾向是相信,当你试图阅读时,写操作仍在完成,但根据文档,这仍然应该返回false。这听起来像是一个内部的.Net错误

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

    • 放一根线,写完后再睡1000毫秒
    • 使用文件信息而不是文件(以防文件中有错误)
    • 不检查文件.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。

    以前从未遇到过此类错误,但我的调试器和Stacktrace似乎有问题,没有提供适当的信息。在大型代码库中,
    列表
    对象在开始时尚未实例化

    通常,我的调试器会告诉我哪个对象没有实例化。不幸的是,它一直在抱怨错误项、
    fileName
    string(bug?)以及其中的任何内容。这也不是在单独的线程中运行的

    经过反复试验后,发现它位于以下线路的下方:

    if (File.Exists(fileName)
    {
          // [...] many lines down. Do lots of stuff.
    
          // Culprit
          Class.ListStringObject.Add("string");
    }
    

    为什么会在这一行中断,我不知道,但我想知道是否有办法。

    尝试在管理模式下启动visual studio。听起来像是权限问题这与
    fileName
    null
    as
    文件无关。在这种情况下,Exists
    将返回
    false
    ,并且
    StReaRead < /COD>构造函数将抛出<代码> AguMutnulLeExabor 基本上在.NET代码中会有非常严重的错误。你可以包括整个堆栈跟踪吗?你给我们展示第19行,但是堆栈跟踪说行39?!?@ MaoDeStrua,我不认为这是重复的,它看起来像是一个真正的bug,不是由OP代码引起的。(现阶段).IsNullOrEmpty返回true,即使字符串已分配。@ThomasWeller
    文件。Exists
    无法引发
    NullReferenceException
    ,但它却会引发OP。这可能是框架中的一个bug或是一个特殊的组合指未知的外部条件。在这种情况下,能够提出一个最小的、完整的和可验证的示例本身就是OP问题的答案。因此,在这种情况下要求一个示例是没有建设性的。运行时上下文是文件运行的目录。它创建时没有问题,写入时没有问题问题,但当检查它是否存在于其他方法中时,它有问题。
    System.IO
    显然是被引用的,因为没有它我将无法写入。写入已经完成,并且已关闭,除非
    using
    语句实际上没有释放锁。但是,情况似乎并非如此:我立即检查文件是否在
    Something()
    方法中存在。只有在调用
    DoSomething()
    时,它才会失败,这是一个唯一的方法名。不检查
    file.exists()
    会导致相同的问题和错误。所有引用文件名的操作似乎都失败。为了澄清,所有引用
    文件名
    的操作都会在它执行File.Exists()的位置,在
    DoSomething()
    StreamReader
    的内部,导致相同的错误并产生相同的调试输出。在
    DoSomething中()
    ,它将在
    File.Exists()或
    StreamReader
    听起来像