C# 以经过对象验证的方式跟踪所采取的行动?
让我们面对现实吧,有些时候你可以简单地跟踪异常并在出现故障时报告这些异常,但大多数时候,当你在执行复杂的操作并处理一个没有构建的库时,你必须自己跟踪正在发生的一切,以便在出现问题时,你可以适当地报告它。否则,您可能会出现一些奇怪的错误,例如:“字符串不能为空”,并且没有更多的信息。。。然而,在您的代码中,可能会有数千行代码出现此错误,这将使解决此错误成为一场噩梦,更不用说向用户报告正确的详细信息了 让我们举一个小例子来说明这一点。。。假设您正在构建一个应用程序,该应用程序从其开发工作站获取IIS的开发人员设置,并使用C# 以经过对象验证的方式跟踪所采取的行动?,c#,C#,让我们面对现实吧,有些时候你可以简单地跟踪异常并在出现故障时报告这些异常,但大多数时候,当你在执行复杂的操作并处理一个没有构建的库时,你必须自己跟踪正在发生的一切,以便在出现问题时,你可以适当地报告它。否则,您可能会出现一些奇怪的错误,例如:“字符串不能为空”,并且没有更多的信息。。。然而,在您的代码中,可能会有数千行代码出现此错误,这将使解决此错误成为一场噩梦,更不用说向用户报告正确的详细信息了 让我们举一个小例子来说明这一点。。。假设您正在构建一个应用程序,该应用程序从其开发工作站获取IIS
Microsoft.Web.Administration
将其应用到某个服务器上。这将涉及多个对象,如站点
,应用程序池
,应用程序
,虚拟目录
,等等。。。可以包含多个属性值的
一旦进入服务器,您就必须获取开发人员设置的每个属性值,并将它们应用到实际的服务器上,这些操作中的任何一个都可能由于某种原因而失败
为了跟踪进度和/或故障以进行正确的报告,您必须实现自己的代码,因为Microsoft.Web.Administration
库在其异常消息中没有提供很多详细信息
我一直这样做的方式是在“应用设置/前端”例程中保留一个本地日志,然后使用它来知道当出现故障时代码在哪里。。。大概是这样的:
try
{
this.log.Add("Applying pool.Failure.AutoShutdownExe");
pool.Failure.AutoShutdownExe = this.deployment.WebSite.VirtualDirectory.ApplicationPool.AutoShutdownExe;
this.log.Add("Successfully applied pool.Failure.AutoShutdownExe");
//.........
}
catch(exception ex)
{
this.log.Add("Deploy failure! Fatal error occurred. " + Environment.Newline +
"Type: " + ex.GetType().Name + Environment.Newline +
"Message: " + ex.Messsage + Environment.Newline +
"Stack Trace: " + Environment.Newline + ex.StackTrace);
//.................
}
- Deployment starting...
- .....
- .....
- Applying pool.Failure.AutoShutdownExe
- Deploy failure! Fatal error occurred.
Type: ArgumentNullException
Message: String cannot be empty
Stack Trace:
......... Line 35.. .
如果在上述点出现故障,则会产生一个非常好且易于阅读的日志,如下所示:
try
{
this.log.Add("Applying pool.Failure.AutoShutdownExe");
pool.Failure.AutoShutdownExe = this.deployment.WebSite.VirtualDirectory.ApplicationPool.AutoShutdownExe;
this.log.Add("Successfully applied pool.Failure.AutoShutdownExe");
//.........
}
catch(exception ex)
{
this.log.Add("Deploy failure! Fatal error occurred. " + Environment.Newline +
"Type: " + ex.GetType().Name + Environment.Newline +
"Message: " + ex.Messsage + Environment.Newline +
"Stack Trace: " + Environment.Newline + ex.StackTrace);
//.................
}
- Deployment starting...
- .....
- .....
- Applying pool.Failure.AutoShutdownExe
- Deploy failure! Fatal error occurred.
Type: ArgumentNullException
Message: String cannot be empty
Stack Trace:
......... Line 35.. .
-部署正在启动。。。
- .....
- .....
-正在应用pool.Failure.AutoShutdownExe
-部署失败!发生了致命错误。
类型:ArgumentNullException
消息:字符串不能为空
堆栈跟踪:
......... 第35行。
这非常有效,因为我可以很容易地看到它失败的地方,但我觉得我花了大部分时间编写这些日志条目,而不是实际编写功能本身,我想知道是否有更简单的方法来做到这一点?例如,通过使“对象”成为“自我感知对象”,跟踪其上次访问的属性,然后用于以后报告或其他内容,从而将此跟踪功能移动到“对象”本身
那么你通常做什么?-不要罗嗦地跟踪,只是脱口而出错误,就这样?
-以类似于我上面所做的方式进行详细跟踪?
-完全不同的东西
有没有一种标准且经验证的方法可以减轻开发人员的负担?我想,在编程时,您会发现编写一个基本版本的程序来实现您想要的功能非常简单,然后您会将大部分时间花在“防御性编程”上—检查常见的异常,检查可能需要抛出异常、验证输入等的条件。作为一个例子,请看一看。虽然日志记录是一件好事,但在单元测试、集成测试和,确保你的输入被消毒,所以你的意思是,这是正常的,一旦你在这里呆了很长一段时间,它就会出现在你的地盘上。。。您花更少的时间编写功能,花更多的时间处理错误并向用户报告“漂亮”消息。。。很公平。但是,在C#中是否有一种“标准”的方法可以帮助程序员更快、更容易地完成这项工作?这正是我要说的。我不知道有什么“标准”。可能有一些库使用反射来检测属性更改,并提供一个可以插入的接口来记录这些更改。如果没有图书馆,你可以写一个。但执行防御性编码仍将取决于您。我不确定它是否适合您的情况,但我最多会重构代码以获得较小的类和方法,并正常依赖堆栈跟踪。我建议阅读Robert C. Martin的《干净代码》,如果你认为这种方法对你有帮助。