我是第一次在WPF中创建测试应用程序。我试图更新从另一个线程(非UI线程)在线程UI中创建的列表框。我面临的问题是,无论我在其他线程中找到的所有建议如何,它似乎都不起作用。它对文本框很有用,但不管这个列表框是什么都不行。
我已经尝试创建一个位于窗口本身的实际控件(如果在代码中声明它将是原因)但它不起作用。
如果我尝试使用BeginInvoke,在运行时没有任何反应,但如果我尝试使用Invoke,应用程序就会永远冻结。这是我到目前为止提出的代码。
按钮单击事件:
Dim TableList As New ListBox
If GetTableList(connection, TableList, DatabaseName, TxtBx_Tasklist) = 0 Then
MsgBox(TableList.Items.Count)
Else
msgbox("FAIL")
End If
GetTableList功能:
Dim ThreadResult As Integer
Dim Thread As New System.Threading.Thread(Sub()
ThreadResult = _GetTableList(SQLConnection, Listbox, DatabaseName, tasklist)
'Thread.Sleep(5000)
End Sub)
Thread.SetApartmentState(ApartmentState.STA)
Thread.Start()
Do Until Thread.ThreadState = System.Threading.ThreadState.Stopped
Loop
If ThreadResult = 0 Then
Return 0
Else
Return 1
End If
_GetTableList功能:
Try
'Make sure listbox is empty
Application.Current.Dispatcher.BeginInvoke(New Action(Sub()
listbox.Items.Clear()
End Sub), DispatcherPriority.Background)
'Declare required components for the SQL operation
Dim command As New MySqlCommand("SHOW tables;")
Dim adapter As New MySqlDataAdapter
Dim data As MySqlDataReader
Dim TableList As New ListBox
'Open connection to the server
SQLConnection.Open()
'Execute the command
command.Connection = SQLConnection
adapter.SelectCommand = command
data = command.ExecuteReader
'Update the tasklist control
Application.Current.Dispatcher.BeginInvoke(New Action(Sub()
tasklist.AppendText("Getting table list for database " & DatabaseName & "...")
End Sub), DispatcherPriority.Background)
'Process data returned from query and store it in a temporary
While data.Read
If data.HasRows Then
TableList.Items.Add(data(0))
'MsgBox(data(0) & " " & listbox.Items.Count)
End If
End While
'Update the tablelist
For Each items In TableList.Items
listbox.Dispatcher.BeginInvoke(New Action(Sub()
listbox.Items.Add(items.ToString)
End Sub))
Next
'Closed SQL connections
SQLConnection.Close()
SQLConnection.Dispose()
'Update tasklist control
tasklist.Dispatcher.BeginInvoke(New Action(Sub()
tasklist.AppendText("...Done! " & listbox.Items.Count & " tables found." & vbNewLine)
End Sub), DispatcherPriority.Background)
'Return 0 to confirm nothing went wrong
Return 0
Catch ex As MySqlException
MsgBox("An error occured while getting the list of tables : " & ex.Number & " , " & ex.Message)
Return 1
End Try
使用BeginInvoke更新任务列表控件(这是一个文本框)效果很好,但出于某种原因,更新列表框效果不佳。
我想要更新列表框的任何想法?
答案 0 :(得分:1)
如果你计划阻塞直到线程完成,你为什么要使用线程?在GUI线程中执行此操作。如果你想在后台运行,请不要阻塞并等待线程完成。
Invoke
死锁,因为您传递给Invoke
的委托在GUI线程上运行,但GUI线程正在等待后台线程完成,因此不处理消息。