1

好的..这是问题

我有一个主 UI 表单,它有一个控件容器,我可以向它添加一些按钮项,而且我还有一个启动侦听器的 backgroundworker 对象。当侦听器事件触发时,我想在主 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
4

5 回答 5

2

假设您将所有 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()
于 2009-05-22T13:24:48.430 回答
1

您不能从 UI 线程以外的其他线程更新 UI 元素。

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

于 2013-02-09T13:52:01.617 回答
0

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

于 2009-02-14T21:24:42.463 回答
0

您必须使用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
于 2009-01-22T19:40:45.100 回答
0

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

这是一个更清晰的例子

Private Sub Notifications() 将 NotificationObj 调暗为新 NotificationEngine()

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

    ' start the notification processor
    NotificationObj.Start()

End Sub

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

于 2009-01-22T20:32:59.893 回答