主 UI 窗口未更新控件 - 跨线程操作无效

发布于 2024-07-13 01:10:03 字数 850 浏览 7 评论 0原文

好吧..这是问题

我有一个主 UI 表单,它有一个控制容器,我可以向其中添加一些按钮项,而且我还有一个启动监听器的后台工作对象。 当监听器事件触发时,我想在主 UI 表单上的控件容器中创建一个按钮。 一切似乎都工作正常,直到我尝试向该容器添加新的控制项。 我收到以下异常

“跨线程操作无效:从创建它的线程以外的线程访问控制‘RadMagnifier_AcceptReject’。”

代码流程如下

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

初见终念 2024-07-20 01:10:03

假设您将所有 UI 操作移至 RunWorkerCompleted 方法中,它看起来像一个错误:

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

我建议使用防弹(伪代码):

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

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()
菩提树下叶撕阳。 2024-07-20 01:10:03

您无法从 UI 线程以外的其他线程更新 UI 元素。

将按钮添加代码添加到 RunWorkerCompleted 事件,因为它将在 UI 线程上触发。
DoWork 事件在线程池线程上运行,而不是在 UI 线程上运行。

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.

别忘他 2024-07-20 01:10:03

您必须使用 RunWorkerCompleted 事件,因为它在 UI 线程上执行。 通过 DoWork 事件在窗体上添加控件是错误的,因为该函数是在与创建主窗体的线程不同的线程上执行的。

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

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
黑寡妇 2024-07-20 01:10:03

嗯..当我将通知过程移动到 RunworkerCompleted 事件中时,它给了我同样的错误。 我无法直接在 RunworkerCompleted 事件中添加按钮,因为通知过程是在创建新按钮之前等待事件发生。

这是一个更清晰的示例

Private Sub notifications()
DimNotificationObj As NewNotificationEngine()

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

    ' start the notification processor
    NotificationObj.Start()

End Sub

然后一旦NotificationReceive事件触发,我就创​​建一个新按钮并将其添加到主窗体上的控件容器中。

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.

热血少△年 2024-07-20 01:10:03

您可以使用 Control.BeginInvoke,从后台线程在表单上调用它,传递一个删除来添加新按钮。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文