gpt4 book ai didi

VB.net、调用、委托(delegate)和线程。无法弄清楚如何跨类使用它们

转载 作者:行者123 更新时间:2023-12-03 12:45:43 24 4
gpt4 key购买 nike

长话短说,我费了好大的劲才弄明白在使用线程时如何使用调用和/或委托(delegate)从单独的类更新用户窗体。我很确定这对有更多经验的人来说是愚蠢和明显的。我知道可能需要一个委托(delegate),但我所有的努力似乎只在从主线程调用时才有效。我已经在互联网上浏览了半天,但有些东西我没有得到。

这里有一些伪代码作为例子:

此选项有效:

Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim t1 As New Threading.Thread(AddressOf Count)

t1.IsBackground = True

t1.Start(100)
End Sub
Private Sub Count(ByVal Max As Object)
If TypeOf Max Is Integer Then
Count(CInt(Max))
End If
End Sub


Private Sub SetLabelText(ByVal text As String)
If Label1.InvokeRequired Then
Label1.Invoke(New Action(Of String)(AddressOf SetLabelText), text)
Else
Label1.Text = text

End If
End Sub

Private Sub Count(ByVal Max As Integer)
For i = 1 To Max
SetLabelText(CStr(i))
Threading.Thread.Sleep(200)
Next
End Sub
End Class

虽然这(我的 1000 次尝试中的一个略有不同的变化)却没有。实际上,对于这个示例,我只是尝试将其中一个潜艇分离到它自己的类中,但它在其他方面与我可以做到的相同:

Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim t1 As New Threading.Thread(AddressOf Count)
t1.Start(100)

End Sub
Private Sub Count(ByVal Max As Object)
If TypeOf Max Is Integer Then
Dim class2 As New class2
class2.Count(CInt(Max))
End If
End Sub

Private Delegate Sub SetTextBoxTextInvoker(text As String)
Sub SetLabelText(ByVal text As String)
'or me.label1, form1.label1 or anything else I can try!
If Me.InvokeRequired Then
Me.Invoke(New SetTextBoxTextInvoker(AddressOf SetLabelText), _
text)
Else
Me.Label1.Text = text
End If
End Sub
End Class

Public Class class2
Sub Count(ByVal Max As Integer)
For i = 1 To Max
form1.SetLabelText(CStr(i))
Threading.Thread.Sleep(200)
Next
End Sub
End Class

据我所知,子“SetLabelText”中 invokerequired 的 if 语句似乎永远不会被触发。我最好的猜测是我在检查 invokerequired 参数时没有正确引用用户窗体?或者我需要向代表提供其他东西?我只是因为弄乱了我可能会出错的数百万个小变量而感到沮丧。提前感谢您提供的任何帮助,如果您需要更多信息,请告诉我。

最佳答案

我不确定我是否理解您要执行的操作,但是基于您的代码,您可以使用以下代码安全地(“线程安全地”)设置标签:

Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim t1 As New Threading.Thread(AddressOf Count)

t1.IsBackground = True

t1.Start(100)
End Sub

Private Sub Count(ByVal Max As Object)
If TypeOf Max Is Integer Then
Dim class2 As New Class2

class2.Count(CInt(Max), AddressOf SetLabelText)
End If
End Sub

Private Sub SetLabelText(ByVal text As String)
If Label1.InvokeRequired Then
Label1.Invoke(New SetText(AddressOf SetLabelText), text)
Else
Label1.Text = text
End If
End Sub
End Class

Public Class Class2
Sub Count(ByVal Max As Integer, SetTextMethod As SetText)
For i = 1 To Max
SetTextMethod.Invoke((CStr(i)))

Threading.Thread.Sleep(200)
Next
End Sub
End Class

Public Delegate Sub SetText(text As String)

我创建了一个名为“SetText”的委托(delegate);当表单调用您的类中的计数函数时,您可以传递引用 SetLabelText 方法的委托(delegate)实例。在该方法中,您可以直接或间接通过 Invoke 以及委托(delegate)的新实例安全地设置标签文本。

你肯定不想做的是从你的类中引用你的表单(即“form1.SetLabelText(CStr(i))”);随着项目规模的增长和需求的变化,这可能会造成真正的噩梦!

如果我误解了您的问题或没有正确回答,请回复。

关于VB.net、调用、委托(delegate)和线程。无法弄清楚如何跨类使用它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18730013/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com