Vb2017:什么以及为什么调用和委托? [英] Vb2017: what and why invoke and delegate?

查看:71
本文介绍了Vb2017:什么以及为什么调用和委托?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,



在下面的代码中,我正在学习线程。

代码运行良好,但仅归功于sub :



Private Sub Form1_Load(ByVal sender As System.Object,ByVal asSystem.EventArgs)Handles MyBase.Load

Me.CheckForIllegalCrossThreadCalls = False

结束子



如果没有这个子,我会收到错误消息。

我明白这是因为我给了外部命令的线程,即:Label1.Text = Number1等。



我知道我现在应该使用invoke和delegate,但我不知道究竟在哪里在这段代码中因为我​​不理解调用和委托非常好..



也许有人可以帮助我更进一步?



谢谢,



Eric







Hello everyone,

In the code below I'm learning threading.
The code runs fine but only thanks to the sub:

Private Sub Form1_Load (ByVal sender As System.Object, ByVal asSystem.EventArgs) Handles MyBase.Load
Me.CheckForIllegalCrossThreadCalls = False
End Sub

Without this sub I get error messages.
I understand that that is because I give the thread outside commands, namely: Label1.Text = Number1 or the like.

I know that I should now use invoke and delegate, but I do not know where exactly in this code because I don't understand invoke and delegate very well..

Maybe someone can help me further?

Thank you,

Eric



Public Class Form1

    Dim Number1 As Integer
    Dim Number2 As Integer
    Dim Thread1 As System.Threading.Thread
    Dim Thread2 As System.Threading.Thread

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.CheckForIllegalCrossThreadCalls = False
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Thread1 = New System.Threading.Thread(AddressOf Telop)
        Thread1.Start()
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Thread2 = New System.Threading.Thread(AddressOf Telaf)
        Thread2.Start()
    End Sub

    Private Sub Telop()
        Do Until Number1 = 10000
            Number1 = Number1 + 1
            Label1.Text = Number1
            'Me.Refresh()
        Loop
    End Sub 'Telop

    Private Sub Telaf()
        Number2 = 10000
        Do Until Number2 = 0
            Number2 = Number2 - 1
            Label2.Text = Number2
            'Me.Refresh()
        Loop
    End Sub 'Telaf

End Class





我尝试过:



vb2017:什么以及为什么调用和委托?



What I have tried:

vb2017: What and why invoke and delegate?

推荐答案

代理是其他语言松散地称为函数指针。



由于您无法从另一个线程触摸控件,您必须使用Sub或Function来更新控件的方式。现在,您必须以某种方式调用此方法,但您必须以我希望此线程调用该方法的方式执行此操作。这就是Invoke的用武之地。



在你的例子中,你可以有一个Sub来设置特定标签控件的Text属性:

Delegates are what other languages loosely refer to as "function pointers".

Since you can't touch a control from another thread, you have to use a Sub or Function to update the control how you want. Now, you have to call this method somehow, but you have to do it in a way that says "I want this thread to call that method." This is where the Invoke comes in.

In your example, you could have a Sub that sets the Text property of a specific label control:
Private Delegate Sub UpdateLabel1Delegate(ByVal message As String)

Private Sub UpdateLabel1Text(ByVal message As String)
    If Label1.InvokeRequired Then
        ' This is a cross-thread call, so
        ' invoke a call back to this method.
        Me.BeginInvoke(New UpdateLabel1Delegate(AddressOf UpdateLabel1Text), message)
    Else
        ' We're being called on the UI thread, so just update the label.
        Label1.Text = message
    End If
End Sub

.
.
.

   ' Code running on a non-UI thread...
   UpdateLabel1Text("This is a test...")


跨线程调用是指当你启动一个新线程并且它试图访问任何UI元素时 - 因为它们被原始线程拥有 - UI线程 - 并且事情开始变得相反梨形如果从多个线程访问相同的控件,就像你在汽车中有一个驱动程序的方式一样:更多人试图在同一时间驾驶也无济于事!



将CheckForIllegalCrossThreadCalls设置为False意味着当您从错误的线程尝试时系统不会引发异常。这不是一件好事:它没有解决潜在的问题,它只是让你的代码不知道他们 - 有点像司机没有被告知后座上的配偶也有方向盘。汽车仍然无法正常工作,但现在司机不知道为什么,因为他没有被告知。更糟糕的是,在您的应用程序因此崩溃之前,您不一定知道您的数据已损坏并且可能会导致一些实际问题(想象一下,如果您的银行不知道它从您的帐户中取款而不是我的帐户)。 />


调用似乎很复杂,但事实并非如此。您所要做的就是使用 Control.InvokeRequired Property [ ^ ]如果已设置,则使用Invoke在原始线程上运行方法:如何:从线程处理控件 [ ^ ]
Cross thread calls are when you start a new thread and it tries to access any UI element - because they are "owned" by the original thread - the UI thread - and things start to go rather pear shaped if the same control is accessed from multiple threads, in exactly the same way that you have one driver in a car: more people trying to steer at the same time would not help!

Setting CheckForIllegalCrossThreadCalls to False means that the system doesn't raise an exception when you do try from the wrong thread. That's not a good thing: it doesn't fix potential problems it just makes your code not know about them - a bit like the driver not being told that his mate in the back seat also has a steering wheel. The car still doesn't work properly, but now the driver doesn't know why because he hasn't been told. Worse, until your app crashes as a result, you won't necessarily know that your data is corrupt and that can cause some real problems (imagine if your bank didn't know it took money from your account instead of mine).

Invoke seems complicated, but it isn't, not really. All you have to do is check what thread you are using the Control.InvokeRequired Property [^] and if it is set, you use Invoke to run a method on the original thread: How to: Manipulate Controls from Threads[^]


首先我建议您阅读更多关于这些事情的内容......



然后 - 你的问题:

你已经宣布了你的2个主题。

使用Button-Click你委托这个线程之一的方法。现在它将被执行。

在你的Thread-Method中,你试图从Main-Thread(Label2)访问一个元素。这是不可能的,因为元素只能属于一个所有者 - 在本例中是Main-Thread。

所以你必须构建一个Invoke-Method,它可以让Control在它能够做到的时候完成它。



但是当你改变你的代码它正常工作(调用)你不会在Label中看到增加值,因为你的线程以毫秒为单位执行它的工作。您应该在方法中输入Thread.Sleep ...
At first I suggest that you read something more about those things ...

Then - to your question :
You have declared your 2 Threads.
With the Button-Click you delegate a Method to one of this Threads. Now it will be executed.
Inside your Thread-Method you try to access an element from the Main-Thread (Label2). This is not possible because an element only can belong to one owner - in this case the Main-Thread.
So you have to build an Invoke-Method which enables the Control to do it's job when it's able to do it.

But when you change your code that it works right (invoking) you would not see an increasing value inside the Label because your Thread executes it's job in Milliseconds. You should enter a Thread.Sleep inside your method ...


这篇关于Vb2017:什么以及为什么调用和委托?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆