警惕beginInvoke的性能陷阱

 Control.BeginInvoke用于异步更新GUI上边的数据,通过是辅助线程得到数据之后需要更新到UI线程上边,由于和UI线程不在一个线程上运行,当需要访问UI上的控件的时候,就会抛出异常。

通常使用Control.BeginInvoke的方法是,使用的是.Net Framework提供的Fun<> 和Action<>等预定义类型。如

         /// <summary>
        /// 接收到新数据
        /// </summary>
        /// <param name="Data"></param>
        private void dtm__OnNewRow(List<string> Data)
        {
            Action<List<string>> myFun = AddNewRowToTable;       
            this.BeginInvoke(myFun, new object[] { Data});
        }

        private void AddNewRowToTable(List<string> data)
        {
           //do something
         }

 这里string 是值类型,所以在调用的过程中会尝试多次的 对象-值和值-对象的封箱和拆箱操作。。引起性能瓶颈。

解决方法是使用 MethodInvoker 的匿名方法,代码如下:

  /// <summary>
        /// 接收到新数据
        /// </summary>
        /// <param name="Data"></param>
        private void dtm__OnNewRow(List<string> Data)
        {
            Action<List<string>> myFun = AddNewRowToTable;
            this.BeginInvoke((MethodInvoker)delegate()
            {
                Row r = new Row();
                foreach (string s in Data)
                {
                    r.Cells.Add(new Cell(s));
                }
                XPtbData.TableModel.Rows.Add(r);

                if (dtm_.DataTableWorkingMode == SensorWorkingMode.One_Triggle_Sensor
                    || dtm_.DataTableWorkingMode == SensorWorkingMode.Two_Triggle_Sensor)
                    UpdateSummaryTable();
            });

            //this.BeginInvoke(myFun, new object[] { Data});
        }

        private void AddNewRowToTable(List<string> data)
        {
            // do something
        }

 

posted @ 2012-12-29 23:23  lvchengwei  阅读(467)  评论(0编辑  收藏  举报