从代码放置位置上来寻找问题的答案

在开发中,会遇到各种各样的问题,其中有一类问题是由于“将代码放置在错误的位置”而导致的。

本文将给出两个简单的实例对这种场景进行模拟,博主希望通过对这两个实例的说明能加深自己对这类问题的理解,也为下次再次碰到这种问题时能早点直指问题本质而提供帮助。

 

实例1

新建Windows应用程序FactorialExp

程序实现在界面中输出计算10的阶乘的中间过程。

程序主画面如下图所示。

 

程序的完整代码如下图所示(有问题的代码)。

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()); })
                    );
            }
        }
    }
}

调试程序

调试程序时,经常会出现“在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。”通过分析异常信息了解到,应该是窗体的初始化还没有完成时就去调用窗体的Invoke 方法,很显然是不可以的。那为什么有时候程序又可以正确执行呢,那是因为恰巧在调用窗体的Invoke方法前完成了窗体的初始化工作。 

修改程序

将线程的初始化与启动工作转移至窗体的Load事件中进行,这样就可以保证在调用Invoke方法前窗体已经完成了初始化。

private void frmFactorial_Load(object sender, EventArgs e)
{
     Thread t = new Thread(new ThreadStart(DoWork));
     t.Start();
}

再次运行程序,不再出现“在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。”的异常了。

说明

从这个实例可以看出,在开发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或者空时才会导致后面的处理有问题。

 

好了,就到这里了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值