VB.net 为后台工作人员内的标签设置值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18844490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 15:05:52  来源:igfitidea点击:

VB.net setting values to labels inside a backgroundworker

vb.netbackgroundworker

提问by Marc Intes

My code works but I am in doubt of what I did because i set CheckForIllegalCrossThreadCalls to false which I think would give some side-effects to my backgroundworker. Here is my sample code:

我的代码有效,但我怀疑我做了什么,因为我将 CheckForIllegalCrossThreadCalls 设置为 false,我认为这会给我的后台工作人员带来一些副作用。这是我的示例代码:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False

End Sub

Private Sub go_Click(sender As Object, e As EventArgs) Handles go.Click

    Try
        If BackgroundWorker1.IsBusy <> True Then
            BackgroundWorker1.RunWorkerAsync()
            resetevent.Set()
        End If

    Catch ex As Exception

    End Try

End Sub


Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

    Do

    Label1.Text = x
Label2.Text = Label1.Text
Label3.Text = Label2.Tex
Label4.Text = Label3.Text
Label5.Text = Label4.Text

    x+=1
    Loop While (x < 100)


End Sub

Private Sub BackgroundWorker1_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    Try



    Catch ex As Exception

    End Try
End Sub

Private Sub BackgroundWorker1_Completed(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted

    Try

    Catch ex As Exception

    End Try
End Sub

Is there a way for me to set values to labels inside a backgroundworker without setting CheckForIllegalCrossThreadCalls to False? Because I have experienced some bugs with my program where the loop suddenly stops even if the counter limit has not been reached yet.

有没有办法让我在后台工作器中为标签设置值而不将 CheckForIllegalCrossThreadCalls 设置为 False?因为我的程序遇到了一些错误,即使尚未达到计数器限制,循环也会突然停止。

回答by UrsulRosu

Create the method

创建方法

  Private Sub setLabelTxt(ByVal text As String, ByVal lbl As Label)
    If lbl.InvokeRequired Then
        lbl.Invoke(New setLabelTxtInvoker(AddressOf setLabelTxt), text, lbl)
    Else
        lbl.Text = text
    End If
End Sub
Private Delegate Sub setLabelTxtInvoker(ByVal text As String, ByVal lbl As Label)

and call setLabelTxt in DoWork.

并在 DoWork 中调用 setLabelTxt。

EDIT:I will add the explanation a bit later with references as I am a bit busy right now. I had your problem also and this worked for me.

编辑:我稍后会在参考资料中添加解释,因为我现在有点忙。我也有你的问题,这对我有用。

EDIT:

编辑:

"The way to safely access controls from worker threads is via delegation.First you test the InvokeRequired property of the control, which will tell you whether or not you can safely access the control. InvokeRequired is one of the few members of the Control class that is thread-safe, so you can access it anywhere. If the property is True then an invocation is required to access the control because the current method is executing on a thread other than the one that owns the control's Handle.

"从工作线程安全访问控件的方法是通过委托。首先你测试控件的 InvokeRequired 属性,它会告诉你是否可以安全地访问控件。InvokeRequired 是 Control 类的少数成员之一是线程安全的,因此您可以在任何地方访问它。如果该属性为 True,则需要调用才能访问控件,因为当前方法正在其他线程上执行,而不是拥有控件句柄的线程。

The invocation is performed by calling the control's Invoke or BeginInvoke method. You create a delegate, which is an object that contains a reference to a method. It is good practice to make that a reference to the current method. You then pass that delegate to the Invoke or BeginInvoke method. That will essentially call the referenced method again, this time on the thread that owns the control's Handle."

调用是通过调用控件的 Invoke 或 BeginInvoke 方法来执行的。您创建一个委托,它是一个包含对方法的引用的对象。将其作为对当前方法的引用是一种很好的做法。然后将该委托传递给 Invoke 或 BeginInvoke 方法。这实际上将再次调用引用的方法,这次是在拥有控件句柄的线程上。”

Source: jmcilhinneypost Accessing Controls from Worker Threadshttp://www.vbforums.com/showthread.php?498387-Accessing-Controls-from-Worker-Threads

来源:jmcilhinney发布从工作线程访问控件http://www.vbforums.com/showthread.php?498387-Accessing-Controls-from-Worker-Threads

I can't explain better than him as I'm a noob also

我无法解释得比他好,因为我也是菜鸟

回答by Ric

During the ProgressChangedevent, you can access the UI as it states in the MSDN documentation:

ProgressChanged活动期间,您可以访问 MSDN 文档中所述的 UI:

The ProgressChanged event handler executes on the thread that created the BackgroundWorker.

ProgressChanged 事件处理程序在创建 BackgroundWorker 的线程上执行。

Thus, if you created the BackGroundWorkeron the UI thread, you can update the UI, eliminating your need to CheckForIllegalCrossThreadCalls

因此,如果您在BackGroundWorkerUI 线程上创建了,则可以更新 UI,从而无需CheckForIllegalCrossThreadCalls

Source:

来源:

MSDN backgroundworker

MSDN后台工作者

回答by Stefan

Just add this line of code on your Form.Load, it should be fine.

只需在您的 Form.Load 上添加这行代码,就可以了。

Control.CheckForIllegalCrossThreadCalls = False

Control.CheckForIllegalCrossThreadCalls = False