这个错误已经出现在许多用户身上,但在我的情况下,Visual studio似乎指向一个字符串对象。我的代码如下:
protected delegate void DPrint_To_LogScreen(string Text, bool NewLine);
protected void Print_To_LogScreen(string Text, bool NewLine)
{
if (InvokeRequired)
Invoke(new DPrint_To_LogScreen(Print_To_LogScreen), new object[] { Text, NewLine }); // exception thrown here from the Text string
else
{
LogScreen.AppendText(Convert.ToString(DateTime.Now) + " -> " + Text + (NewLine ? System.Environment.NewLine : ""));
if (Log_Screen_File == null)
{
Log_Screen_File = new StreamWriter(@"Global.log", true);
Log_Screen_File.WriteLine(Convert.ToString(DateTime.Now) + " -> " + Text);
Log_Screen_File.Close();
}
else
{
lock (Log_Screen_File)
Log_Screen_File.WriteLine(Convert.ToString(DateTime.Now) + " -> " + Text);
}
}
}
我通常想从不同的地方和线程调用函数Print_To_LogScreen。
我期望"if (Log_Screen_File == null)"语句可以完成这项工作(并且在一般情况下它可以工作),但现在异常是由调用命令上的 Text 对象引发的!!
这甚至可能还是Visual Studio意味着输出文件?如果是这样,为什么"if (Log_Screen_File == null)"不起作用?
谢谢
调用Close
不会将其设置为 null
。另外,您应该在此处使用using
。将代码更改为:
if (Log_Screen_File == null)
{
using (Log_Screen_File = new StreamWriter(@"Global.log", true))
{
Log_Screen_File.WriteLine(Convert.ToString(DateTime.Now) + " -> " + Text);
}
Log_Screen_File = null;
}
它具有与上述代码相同的功能,只是它不会引发您当前获得的异常。
不过,很难说你真正想发生什么。在我看来,你似乎有一个潜在的问题。假设线程 A 和线程 B 正在执行。线程 A 看到该Log_Screen_File == null
并创建它。然后线程 B 获取一个时间片并看到该文件存在。然后线程 A 获取另一个时间片,写入文件并关闭它。然后,线程 B 将尝试写入不存在的文件。
如果此代码将由多个线程使用,则必须确保整个操作是原子的。我建议:
private readonly object logLock = new object();
protected void Print_To_LogScreen(string Text, bool NewLine)
{
if (InvokeRequired)
Invoke(new DPrint_To_LogScreen(Print_To_LogScreen), new object[] { Text, NewLine }); // exception thrown here from the Text string
else
{
lock (logLock)
{
LogScreen.AppendText(Convert.ToString(DateTime.Now) + " -> " + Text + (NewLine ? System.Environment.NewLine : ""));
if (Log_Screen_File == null)
{
using (Log_Screen_File = new StreamWriter(@"Global.log", true))
{
Log_Screen_File.WriteLine(Convert.ToString(DateTime.Now) + " -> " + Text);
}
Log_Screen_File = null;
}
else
{
Log_Screen_File.WriteLine(Convert.ToString(DateTime.Now) + " -> " + Text);
}
}
}
}
但是你真的想每次都打开和关闭文件吗?你不会这样做吗:
if (Log_Screen_File == null)
{
Log_Screen_File = new StreamWriter(@"Global.log", true);
}
Log_Screen_File.WriteLine(Convert.ToString(DateTime.Now) + " -> " + Text);
当然,假设您在程序退出时关闭日志文件。
想想看,您可能根本不需要锁,因为该方法正在 UI 线程上执行。但是,锁不会造成任何伤害,也不会影响性能。