0

0

C# 性能优化最佳实践

黄舟

黄舟

发布时间:2017-02-25 11:04:45

|

2006人浏览过

|

来源于php中文网

原创

1、显式注册的evenhandler要显式注销以避免内存泄漏

将一个成员方法注册到某个对象的事件会造成后者持有前者的引用。在事件注销之前,前者不会被垃圾回收。

private void Form1_Load()
{
  ……
  //注册事件
  CommandRemotingContext.CmdChanged += new ReciverCmdStateChangedEventHandler(this.CommandRemotingContext_CmdChanged);
  ……
}
private void Form1_FromClosed()
{
  ……
  //关闭窗体时及时释放事件
  CommandRemotingContext.CmdChanged -= new ReciverCmdStateChangedEventHandler(this.CommandRemotingContext_CmdChanged);
  ……
}

由事件引起的内存泄漏问题:

  • 对象A订阅了对象B中的事件

  • 对象A的生命周期远远大于对象B

  • 对象A没有取消订阅对象B的时间

  • 最终导致对象B无法释放

2、控件绑定的数据源批量操作应避免自动刷新

  • 客户端批量操作数据时,控件自带的刷新操作,会造成不必要的时间消耗

  • 当数据源(如DataTable、Array、List、ObservableCollection或其他IListSource等)被绑定到控件时,批量操作数据时应该断开绑定或挂起控件的刷新。

    this.gcBillList.DataSource = null;
    DataRowCollection rows = this.ds.Tables[0].Rows;
    foreach (DataRow row in rows)
    {
        // DataRow数据操作
    }
    this.gcBillList.DataSource = this.ds.Tables[0].DefaultView;

3、减少客户端与服务端的通信次数

  • WebService调用并非越少越好,传输数据量较大的情况可考虑拆分为多次调用

  • 对于短WebService的调用,应尽量合并以减少交互次数

    //多次调用了相同的WS  
    txtCompanyName.Text=SCPubFunctionClient.PublicWSCal(“ForTest”, “GetCompanyNameByID”,“0001”);  txtCompanyInnerName.Text=SCPubFunctionClient.PublicWSCal(“ForTest”, “GetCompanyInnerNameByID”,“0001”);
    //合并相邻的WS  
    string[] result=SCPubFunctionClient.PublicWSCal(“ForTest”, “GetCompanyNameAndInnerNameByID”,“0001”);
    txtCompanyName.Text=result[0];
    txtCompanyInnerName.Text= result[1];

4、减少客户端与服务端的通信次数

如非必要,应尽量避免在循环体内重复调用WebService

//循环调用了相同的WS  
List persons;
……
foreach(string personID in personIDs)
{
	person=HRPubWsClient.getPerson(personID);
	persons.Add(person);
}
//合并WS  
List persons;
……
persons =HRPubWsClient.getPersonList(personIDs);

5、使用泛型来避免装箱、拆箱操作(减少垃圾回收压力)