在开发中,会遇到各种各样的问题,其中有一类问题是由于“将代码放置在错误的位置”而导致的。
本文将给出两个简单的实例对这种场景进行模拟,博主希望通过对这两个实例的说明能加深自己对这类问题的理解,也为下次再次碰到这种问题时能早点直指问题本质而提供帮助。
实例1
1 新建Windows应用程序FactorialExp。
程序实现在界面中输出计算10的阶乘的中间过程。
程序主画面如下图所示。
2 程序的完整代码如下图所示(有问题的代码)。
using System;
using System.Threading;
using System.Windows.Forms;
namespace FactorialExp
{
public partial class frmFactorial : Form
{
public frmFactorial()
{
InitializeComponent();
Thread t = new Thread(new ThreadStart(DoWork));
t.Start();
}
private void DoWork()
{
double result = 1;
for (int i = 1; i < 11; i++)
{
result *= i;
this.Invoke(
new Action(() => { this.lsvResult.Items.Add(result.ToString()); })
);
}
}
}
}
3 调试程序
调试程序时,经常会出现“在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。”通过分析异常信息了解到,应该是窗体的初始化还没有完成时就去调用窗体的Invoke 方法,很显然是不可以的。那为什么有时候程序又可以正确执行呢,那是因为恰巧在调用窗体的Invoke方法前完成了窗体的初始化工作。
4 修改程序
将线程的初始化与启动工作转移至窗体的Load事件中进行,这样就可以保证在调用Invoke方法前窗体已经完成了初始化。
private void frmFactorial_Load(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(DoWork));
t.Start();
}
再次运行程序,不再出现“在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。”的异常了。
5 说明
从这个实例可以看出,在开发WinForm程序时,应该在合适的事件处理程序中添加我们的代码,否则会导致程序错误。其实,在开发Web程序时,这点也是需要被考虑的。
实例2
直接给出下面的示例代码。
using System;
namespace HandleExceptionExp
{
class Program
{
static void Main(string[] args)
{
string returnName=string.Empty;
try
{
returnName = GetName();
}
catch (Exception e)
{
//将异常信息记入log文件(此部分代码省略)
returnName = string.IsNullOrEmpty(returnName) ? "tiana" : returnName;
}
//接下来使用变量returnName进行其他程序处理
}
static string GetName()
{
string result;
try
{
//获取result的值,此处为了演示不作任何处理,仅赋值Empty
result = string.Empty;
}
catch(Exception e)
{
throw e;
}
return result;
}
}
}
代码中存在一个问题,那就是:当GetName方法正确执行并返回了值returnName时(也就是说没有异常发生时),“returnName = string.IsNullOrEmpty(returnName) ? "tiana" : returnName;”这部分代码是无法被执行到的,但是这段代码应该是不管GetName方法有无正确返回值都应该被执行的,所以应该将这行代码移至异常处理代码块的外部。
string returnName=string.Empty;
try
{
returnName = GetName();
}
catch (Exception e)
{
//将异常信息记入log文件(此部分代码省略)
}
returnName = string.IsNullOrEmpty(returnName) ? "tiana" : returnName;
这个小实例是在一次代码评审时发现的小问题,问题虽小,但是很是隐蔽,因为只有returnName为null或者空时才会导致后面的处理有问题。
好了,就到这里了。