Main UI windows not updating control -Cross-thread operation not valid

巧了我就是萌 提交于 2019-12-24 17:29:46

问题


Ok..here is the problem

I have a main UI form that has a control container that i can add some buttons item to it,and also i have a backgroundworker object that starts up a listner. When the listner events fire, i would like to create a button in that control container on the main UI form. Everything seems to work fine until i try to add a new control item to that container. I get the following exception

"Cross-thread operation not valid: Control 'RadMagnifier_AcceptReject' accessed from a thread other than the thread it was created on."

the code flows like this

Private Sub Mainform_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Me.SessionTableAdapter.Fill(Me.BCSSDataSet1.Session)
    FormatColumns()
    Me.BackgroundWorker2.RunWorkerAsync()
End Sub

Private Sub BackgroundWorker2_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker2.DoWork
    Notifications()
End Sub


Private Sub Notifications()
    'Start listing for events when event is fired try to add a button to a controls container on the UI thread, and that when i get the problem
End Sub

回答1:


Assuming you moved all UI operations into the RunWorkerCompleted method, it looks like a bug:

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=116930 http://thedatafarm.com/devlifeblog/archive/2005/12/21/39532.aspx

I suggest using the bullet-proof (pseudocode):

if(control.InvokeRequired)
  control.Invoke(Action);
else
  Action()



回答2:


You should check out the follow article

http://msdn.microsoft.com/en-us/library/ms171728.aspx

and for more in-depth information read this

http://weblogs.asp.net/justin_rogers/pages/126345.aspx




回答3:


You cannot update UI elements from other threads other than the UI thread.

Add the button add code to RunWorkerCompleted Event, since that will be fired on the UI thread. The DoWork event runs on a thread pool thread not on the UI thread.




回答4:


You have to use the RunWorkerCompleted event because it is executed on the UI thread. Adding controls on the form from the DoWork event is wrong because this function is executed on a different thread than the one that created the main form.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Me.BackgroundWorker1.RunWorkerAsync()
End Sub

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Thread.Sleep(1000)
    'Do not modify the UI here!!!
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    Me.Controls.Add(New Button())
End Sub



回答5:


Hmm..when i move the Notification procedure into the RunworkerCompleted event it gives me the same error. I cant add the button in the RunworkerCompleted event directly because the Notification procedure is wait for event to happen before creating the new button.

Here is a more clear example

Private Sub Notifications() Dim NotificationObj As New NotificationEngine()

    ' register a handler to listen for receive events
    AddHandler Noification.ReceiveCompleted, AddressOf NotificationReceive

    ' start the notification processor
    NotificationObj.Start()

End Sub

And then once the NotificationReceive event fires thats when i create a new button and add it to the controls container on the main form.




回答6:


You could use Control.BeginInvoke, calling it on your form, from the background thread, passing a deleate to add the new button.



来源:https://stackoverflow.com/questions/470390/main-ui-windows-not-updating-control-cross-thread-operation-not-valid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!