加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

wpf – 更新UI异步?

发布时间:2020-12-17 07:14:48 所属栏目:百科 来源:网络整理
导读:考虑这个例子: Private Sub Button_Click( sender As Button,e As RoutedEventArgs) Handles btn.Click sender.IsEnabled = False Thread.Sleep(5000) sender.IsEnabled = TrueEnd Sub 在我的场景中,Button_Click是VM中的命令委托,而Thread.Sleep是一个长时
考虑这个例子:

Private Sub Button_Click(
    sender As Button,e As RoutedEventArgs) Handles btn.Click

  sender.IsEnabled = False

  Thread.Sleep(5000)

  sender.IsEnabled = True
End Sub

在我的场景中,Button_Click是VM中的命令委托,而Thread.Sleep是一个长时间运行的过程(大约2-10秒).

我想,当用户调用命令时,它应立即更新禁用按钮的UI,以便用户在运行时无法执行,然后执行该操作,然后,当操作完成时,取消阻止按钮.

我尝试包装中间线,如下所示:

Dispatcher.BeginInvoke(Sub() Thread.Sleep(5000))

但它没有完成这项工作.
最好的方法是什么?

解决方法

您也可以使用 BackgroundWorker Control来代替创建自己的线程.
通过调用方法“RunWorkerAsync”,可以在另一个线程中调用DoWork事件.

通过从UI线程调用方法“CancelAsync”,您可以将Backgroundworker设置为“Cancellation Pending”(控件的属性“CancellationPending”则为true).在长时间运行的后台线程中,您可以检查该属性(例如,如果您有一个循环:一旦CancellationPending为true,立即退出循环).这是安全中止线程的一个非常好的功能.

除了Backgroundworker之外,您还可以报告线程的进度(例如,在ProgressBar中使用)

例:

Public Class Form1

   Private Sub Form1_Load(sender As Object,e As System.EventArgs) Handles Me.Load

      '** Set to true if you want the ReportProgress Event
      BackgroundWorker1.WorkerReportsProgress = True
      BackgroundWorker1.WorkerSupportsCancellation = True
   End Sub

   Private Sub BackgroundWorker1_DoWork(sender As System.Object,e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

      Dim i As Integer
      Dim n As Integer = 100
      Dim iLastPerc As Integer


      While Not BackgroundWorker1.CancellationPending AndAlso i < n

         '** Do your time consuming actions here
         Threading.Thread.Sleep(500)

         If Math.Floor((i / n) * 100) > iLastPerc Then
            '** If the Progress has changed. Report
            iLastPerc = CInt(Math.Floor((i / n) * 100))
            BackgroundWorker1.ReportProgress(iLastPerc)
         End If

         i += 1
      End While

   End Sub

   Private Sub btnStart_Click(sender As System.Object,e As System.EventArgs) Handles btnStart.Click

      '** Run the Backgroundworker
      BackgroundWorker1.RunWorkerAsync()

   End Sub

   Private Sub BackgroundWorker1_ProgressChanged(sender As Object,e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged

      '** Update the ProgressBar
      ProgressBar1.Value = e.ProgressPercentage

   End Sub

   Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object,e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted

      '** Worker is done. Check for Exceptions or evaluate the Result Object if you like

   End Sub

   Private Sub btnCancel_Click(sender As System.Object,e As System.EventArgs) Handles btnCancel.Click

      '** Cancel the worker
      BackgroundWorker1.CancelAsync()

      MsgBox("Finished!")

   End Sub
End Class

在提到您的问题时,代码应为:

Private Sub btn_Click(sender As Button,e As RoutedEventArgs) Handles btn.Click
  sender.IsEnabled = False
  Using bw As New BackgroundWorker()
    AddHandler bw.DoWork,Sub(s,ea) Thread.Sleep(5000)
    AddHandler bw.RunWorkerCompleted,ea) sender.IsEnabled = True
    bw.RunWorkerAsync()
  End Using
End Sub

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读