我想验证我们的代码并检查我们执行的每个Thread是否都在try catch块中运行。
有效样本:
Thread loadDataThread = new Thread(new ThreadStart(LoadData));
public void LoadData()
{
try {/*do something*/}
catch(Exception ex) { /*Handle exception*/ }
}
无效样本:
Thread loadDataThread = new Thread(new ThreadStart(LoadData));
public void LoadData()
{
/* do something */
}
这是否可以通过FxCop或其他工具进行验证。类似的规则可以应用于其他一些事情,例如。定时器滴答等...
答案 0 :(得分:1)
有关如何在FxCop规则中检测包装try / catch块的示例,请参阅http://social.msdn.microsoft.com/Forums/en-US/vstscode/thread/a257a910-126e-4c8d-aab3-3199347346ec。实际上有点棘手的是检测哪些方法易于从后台线程运行,因为它们并非都是使用Thread.Start或ThreadPool.QueueUserWorkItem等明显的启动程序生成的。
也就是说,你可能想重新考虑将你的方法从添加包装try / catches转换为使用为你添加try / catch的自定义线程启动器。 (然后,您可以创建一个FxCop规则来验证是否正在使用自定义启动器/帮助程序而不是基本框架类似物。)这样可以让您系统地将其他更改应用于所有线程(例如:设置文化,跟踪启动堆栈跟踪以便在以后的异常日志记录中使用,等等,而无需更改从生成的线程运行的所有方法。
答案 1 :(得分:0)
我不知道您是否可以在FXCop中为此添加自定义规则,但您可以使用Mono.Cecil
来执行此操作,但并非如此简单。
答案 2 :(得分:0)
This是用于滚动自己的FxCop规则的非常好的资源。你可以通过谷歌搜索找到许多其他的。
我相信您可以开始查看Thread构造函数的调用者。然后在调用语句中,您可以通过查看delegate参数来获取线程过程的地址。一旦获得方法ref,您需要在方法体内检查您希望的结构的语句。
答案 3 :(得分:0)
这不会直接回答你的问题,但可能是相关的。
您是否有兴趣执行上述操作,因为您不希望应用程序在线程抛出未捕获的异常时退出/崩溃?如果是,则可以将以下内容添加到配置部分中的app.config文件中:
<runtime>
<legacyUnhandledExceptionPolicy enabled="1"/>
</runtime>
免责声明不建议执行上述操作,但可以在最后的情况下使用。
警告:如果您决定使用上述内容,您的应用程序将不会报告任何错误,并尽可能继续执行。因此,您应该拥有一个至少通过
记录任何未捕获的异常的处理程序 void AppStartup()
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
//log error
}