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,并查看流是否给您提供了更具描述性的错误
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
听起来像