You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.Net WinForm用Async/Await实现RadGridView数据导入及进度条更新

实现方案

核心改造思路

  • 将按钮点击事件改为异步事件处理程序,用Async/Await语法实现非阻塞调用
  • 拆分逻辑:耗时的数据库插入操作全部放在后台线程执行,UI线程只负责控件状态更新、进度展示
  • 采用IProgress(Of T)实现线程安全的进度条更新,无需手动处理跨线程控件调用
  • 导入过程中禁用提交按钮、显示进度条,避免重复提交操作

完整修改代码

1. 窗体Load事件(无强制改动,可选异步加载数据避免启动卡UI)

Private Async Sub Import_Payroll_Review_Load(sender As Object, e As EventArgs) Handles Me.Load
    ' 可选:把数据加载也改为异步,避免窗体启动时卡顿
    rgImport.DataSource = Await Task.Run(Function() DataAPI.HR_Payroll_Import_GetData())
    ProgressBar1.Minimum = 0
    ProgressBar1.Maximum = 100
    ProgressBar1.Visible = False
End Sub

如果不需要异步加载数据,原Load代码可以直接保留。

2. 异步提交按钮事件

Private Async Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
    Select Case MsgBox("Are you sure you are ready to import?", MsgBoxStyle.YesNo, "Import Records")
        Case MsgBoxResult.Yes
            ' 先更新UI状态,防止重复操作
            btnSubmit.Enabled = False
            Label1.Text = "正在导入数据,请稍候..."
            ProgressBar1.Value = 0
            ProgressBar1.Visible = True

            ' 获取待导入数据,若该接口耗时也可以包到Task.Run里
            Dim dt As DataTable = DataAPI.HR_Payroll_Import_GetRecordsToImport()
            Dim iTotalRows As Long = dt.Rows.Count
            Dim successCount As Long = 0
            Dim failCount As Long = 0

            ' 声明进度更新回调,自动在UI线程执行
            Dim progress = New Progress(Of Integer)(Sub(percent)
                                                        ProgressBar1.Value = percent
                                                    End Sub)

            ' 后台执行插入逻辑
            Await Task.Run(Sub()
                               Dim currentIndex As Long = 0
                               For Each dr As DataRow In dt.Rows
                                   Dim insertResult As Boolean
                                   If dr("AfterHours") = 0 Then
                                       insertResult = DataAPI.HR_Payroll_TimeCards_Insert(dr)
                                   Else
                                       insertResult = DataAPI.HR_Payroll_TimeCards_Insert_Double(dr)
                                   End If

                                   ' 统计结果
                                   If insertResult Then
                                       successCount += 1
                                       Debug.Print("Inserted Row into TimeCard.Current")
                                   Else
                                       failCount += 1
                                       Debug.Print("Failed to insert row into TimeCard.Current")
                                   End If

                                   ' 计算并上报进度
                                   currentIndex += 1
                                   Dim percent = CInt(Math.Truncate(currentIndex * 100 / iTotalRows))
                                   progress.Report(percent)
                               Next
                           End Sub)

            ' 全部完成后更新UI
            ProgressBar1.Visible = False
            Label1.Text = "请核查下方展示的记录"
            btnSubmit.Enabled = True
            MsgBox($"导入完成:成功{successCount}条,失败{failCount}条", vbInformation, "操作完成")

        Case Else
            Exit Sub
    End Select
End Sub

关键说明

  1. 异步事件处理程序用Async Sub声明是.NET的规范用法,仅可用于事件处理场景,其余异步方法请返回Task/Task(Of T)
  2. Progress(Of T)的回调会自动封送到UI线程执行,不需要手动调用Invoke处理跨线程控件访问问题
  3. 若你的DataAPI提供了对应插入方法的异步实现(比如InsertAsync/Insert_DoubleAsync),可以把Task.Run里的同步调用替换为Await异步调用,后台线程资源占用会更低

内容的提问来源于stack exchange,提问作者Eric Lindros

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 21:00:04