我们在应用程序中遇到问题,我们在TextBox的LostFocus上调用异步进程,然后异步进程需要能够更新主窗体UI(或从主窗体UI显示对话框) )异步运行时。
我们已经考虑过回调并使其真正异步,但我们需要以正确的顺序执行所有操作,这适用于数据录入系统,其中数据输入的速度和准确性非常重要。
示例代码显示了我们要执行的操作,如果切换到BeginInvoke,则处理顺序不正确。
公共类Form1
Private Sub TextBox1_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.LostFocus
' execute the server subroutine
Dim dlgt As New MethodInvoker(AddressOf Me.AsyncProcess)
TextBox1.Text = "1"
' textbox should say 1
' call the server subroutine asynchronously, so the main thread is free
Dim ar As IAsyncResult = dlgt.BeginInvoke(Nothing, Nothing)
While ar.IsCompleted = False
' Application.DoEvents()
End While
' textbox should now say 2
TextBox1.Text = "3"
' textbox should now say 3
End Sub
Public Sub AsyncProcess()
UpdateTextBox()
End Sub
Public Sub UpdateTextBox()
If Me.InvokeRequired Then
Me.Invoke(New MethodInvoker(AddressOf UpdateTextBox), "2")
Else
TextBox1.Text = "2"
End If
End Sub
结束班
有人知道我们如何在主表单线程上调用其他东西,而仍在忙着处理LostFocus事件吗?
提前致谢。
答案 0 :(得分:2)
查看BackgroundWorker课程。您可以使用此类在后台执行长时间运行的任务,并通过事件将状态报告回UI。该类支持“ProgressChanged”事件和“RunWorkerCompleted”事件。我在下面列出了一些示例代码,以展示如何使用它来完成您正在尝试的操作。
Imports System.ComponentModel
Imports System.Threading
Public Class Form1
Private Sub TextBox1_LostFocus(ByVal sender As Object,
ByVal e As System.EventArgs) Handles TextBox1.LostFocus
TextBox1.Text = "1"
' Execute the long-running task in the background
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object,
ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
' Do your heavy lifting in this method; report progress as needed by
' calling ReportProgress, which will in turn call Progress_Changed
' safely on the UI thread. (DO NOT update the UI directly from here.)
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
' Simulate processing for a second
Thread.Sleep(1000)
' Report progress to the UI (the first arg is the percentage complete;
' the secong arg can be a string or any object)
worker.ReportProgress(50, "2")
' Simulate processing for another second
Thread.Sleep(1000)
End Sub
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object,
ByVal e As ProgressChangedEventArgs)
Handles BackgroundWorker1.ProgressChanged
' Update the UI with progress from the background task
TextBox1.Text = CType(e.UserState, String)
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object,
ByVal e As RunWorkerCompletedEventArgs)
Handles BackgroundWorker1.RunWorkerCompleted
' Update the UI when the background task is finished
TextBox1.Text = "3"
End Sub
End Class
答案 1 :(得分:0)
我认为你最好的选择是不要试图等待方法同步完成。将异步调用后要实现的LostFocus处理程序方法的其余部分更改为回调并将其传递给BeginInvoke
。这允许UI线程在维持操作顺序的同时保持响应。