大数据量填充UI的技巧

时间:2010-02-21 09:37:27  来源:第二电脑网  作者:第二电脑网

  第二电脑网导读:索的结果。由于在设计之初没有考虑分页处理,所以导致客户没有输入检索条件的时候,需要在界面上显示几万到几十万条记录。由于数据量非常大,导致UI的填充时间非常的漫长,为了提高UI填充的速度,采用了异步处理的方式,最初的处理方式如下:    1 '数据传送事件    2 Sub DataRowTransport(ByVal sender As Object, ByVal e As DataRowTransportEventAr...
  正文:这个内容本来已经在我过去的一篇随笔中略有提及,但是没有详细的说明这个问题。今天我就这个问题详细的讨论一下。这个问题的提出其实是一个源于一个设计缺陷或者错误。我所在的公司开发了一个财务系统,这个系统中有一张报表,这个报表的主要功能是显示数据检索的结果。由于在设计之初没有考虑分页处理,所以导致客户没有输入检索条件的时候,需要在界面上显示几万到几十万条记录。由于数据量非常大,导致UI的填充时间非常的漫长,为了提高UI填充的速度,采用了异步处理的方式,最初的处理方式如下:
   1 '数据传送事件
   2 Sub DataRowTransport(ByVal sender As Object, ByVal e As DataRowTransportEventArgs)
   3
   4 '判断是否要进行线程调度
   5 If Me.InvokeRequired Then
   6
   7 '调度线程
   8 Me.BeginInvoke(New DataRowTransportHandler(AddressOf DataRowTransport), New Object() {sender, e})
   9 Else
  10
  11 '将数据填充到Grid
  12 Me.FillGrid(e.Data)
  13
  14 '响应事件处理
  15 Application.DoEvents()
  16
  17 '判断是否退出
  18 If Me.Cancel Then
  19
  20 e.Cancel = True
  21 End If
  22 End If
  23 End Sub 从代码的角度来看这段代码是没有什么问题的,基础上是微软提出的线程调度的最佳实践了,但是在实际中运用效果很不理想:界面不能刷新也不能响应取消操作(用户可以选择取消填充)。其实仔细想一想也不难明白,由于数据量很大,导致调用BeginInvoke的调用次数很大,而且两次之间的调用间隔很短,基础上把UI线程的消息循环给填满了,几乎没有机会来响应界面的操作了。
  经过分析之后,发现了一个较好的解决方案,代码如下: 1 '数据缓存
   2 Private _buffer As New ArrayList
   3
   4 '数据填充队列
   5 Private _dataQueue As New Queue
   6
   7 '数据传送事件,由数据传输线程触发
   8 Sub DataRowTransport(ByVal sender As Object, ByVal e As DataRowTransportEventArgs)
   9
  10 '添加到缓存
  11 Me._buffer.Add(e.Data)
  12
  13 '判断是否需要添加到填充队列中
  14 If Me._buffer.Count > 100 Then
  15
  16 '锁定
  17 SyncLock Me._dataQueue
  18
  19 '添加到队列中
  20 Me._dataQueue.Enqueue(Me._buffer.ToArray())
  21 End SyncLock
  22
  23 '清除数据
  24 Me._buffer.Clear()
  25 End If
  26
  27 '判断是否退出
  28 If Me.cancel Then
  29
  30 e.Cancel = True
  31 End If
  32 End Sub
  33
  34 '填充数据,在UI线程调用
  35 Sub FillData()
  36
  37 '用于保存临时数据
  38 Dim tempData As Object
  39
  40 While (True)
  41
  42 '设置数据为空
  43 tempData = Nothing
  44
  45 '判断是否取消
  46 If Me.cancel Then
  47
  48 '退出循环
  49 Exit While
  50 End If
  51
  52 '判断是否有数据
  53 If Me._dataQueue.Count > 0 Then
  54
  55 SyncLock Me._dataQueue
  56
  57 '判断是否有数据,检查两次尽可能的避免同步线程
  58 If Me._dataQueue.Count > 0 Then
  59
  60 '填充界面
  61 tempData = Me._dataQueue.Dequeue()
  62 End If
  63
  64 End SyncLock

"大数据量填充UI的技巧"由第二电脑网原创提供,转载请注明:http://www.002pc.com/master/College/Programming/aspnet/12856.html


关键字:

关于《大数据量填充UI的技巧》文章的评论

站内搜索: 高级搜索

热门搜索: Windows style 系统 tr IP QQ CPU 安装 function 注册 if td