메인 스레드에 NumericUpDown
컨트롤이 있습니다.BackgroundWorker 및 공유 클래스
나는 NumericUpDown
값을 저장하는 공개 class_A
의 인스턴스를 만듭니다.
별도의 스레드를 실행하는 BackgroundWorker
을 만듭니다.
BackgroundWorker
스레드에서 class_A
의 인스턴스에서 인수를 호출하는 class_B
의 인스턴스를 만듭니다.
class_A
의 인스턴스가 방금 전에 생성 된 결과가 Nothing
인 이유를 알 수 없습니다. 여기
Imports System.ComponentModel
Public Class Form1
Dim WithEvents bgw As New BackgroundWorker
Dim WithEvents bgw2 As New BackgroundWorker
Dim lSide As Label
Public nudSide As NumericUpDown
Dim bCalculate As Button
Dim bCalculate2 As Button
Dim tbLog As TextBox
Dim calc As calc
Public calc2 As calc2
Public Delegate Function d_getSide() As Double
Public getSide As New d_getSide(AddressOf rungetSide)
Public Side As c_Side
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Size = New Size(400, 160)
bgw.WorkerSupportsCancellation = True
bgw2.WorkerSupportsCancellation = True
lSide = New Label
With lSide
.Text = "Side"
.Size = New Size(40, 20)
.Location = New Point(10, 10)
End With
Me.Controls.Add(lSide)
nudSide = New NumericUpDown
With nudSide
.Size = New Size(40, 20)
.Location = New Point(lSide.Location.X + lSide.Size.Width, lSide.Location.Y)
.DecimalPlaces = 0
.Minimum = 1
.Maximum = 100
.Increment = 1
.Value = 1
End With
Me.Controls.Add(nudSide)
bCalculate = New Button
With bCalculate
.Text = "Calculate"
.Size = New Size(60, 20)
.Location = New Point(nudSide.Location.X + nudSide.Size.Width + 40, nudSide.Location.Y)
AddHandler .Click, AddressOf bCalculate_Click
End With
Me.Controls.Add(bCalculate)
bCalculate2 = New Button
With bCalculate2
.Text = "Calculate 2"
.Size = New Size(60, 20)
.Location = New Point(bCalculate.Location.X + bCalculate.Size.Width + 10, bCalculate.Location.Y)
AddHandler .Click, AddressOf bCalculate2_Click
End With
Me.Controls.Add(bCalculate2)
tbLog = New TextBox
With tbLog
.Size = New Size(250, 60)
.Location = New Point(lSide.Location.X, lSide.Location.Y + 40)
.Multiline = True
.ScrollBars = ScrollBars.Vertical
End With
Me.Controls.Add(tbLog)
End Sub
Private Sub bCalculate_Click()
bgw.RunWorkerAsync(nudSide.Value)
End Sub
Private Sub bgw_Dowork(sender As Object, e As DoWorkEventArgs) Handles bgw.DoWork
'example 1)
'passing argument throught backGroundWorker
calc = New calc(e.Argument)
End Sub
Private Sub bgw_Runworkercompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
getResult()
End Sub
Private Sub bCalculate2_Click()
'here i create an instance of the Side class (expose the side property)
Side = New c_Side
bgw2.RunWorkerAsync()
End Sub
Private Sub bgw2_Dowork(sender As Object, e As DoWorkEventArgs) Handles bgw2.DoWork
'example 2)
' in the backgroundworker thread i create an instance of the class calc2
calc2 = New calc2()
End Sub
Private Sub bgw2_Runworkercompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles bgw2.RunWorkerCompleted
getResult2()
End Sub
Private Sub write(ByVal message As String)
With tbLog
.SelectionStart = .Text.Length
.SelectedText = vbCrLf & message
End With
End Sub
Private Sub getResult()
tbLog.Clear()
write("area = " & calc.area & " cm^2")
write("volume = " & calc.volume & " cm^3")
End Sub
Private Sub getResult2()
tbLog.Clear()
write("area = " & calc2.area & " cm^2")
write("volume = " & calc2.volume & " cm^3")
End Sub
Public Function rungetSide() As Double
If Me.InvokeRequired Then
Me.Invoke(getSide)
Else
Return Side.Side
End If
Return Side.Side
End Function
End Class
Class calc
Sub New(ByVal Side As Double)
_area = Side^2
_volume = Side^3
End Sub
Private _area As Double
Public Property area As Double
Get
Return Math.Round(_area, 2)
End Get
Set(value As Double)
_area = Math.Round(value, 2)
End Set
End Property
Private _volume As Double
Public Property volume As Double
Get
Return Math.Round(_volume, 2)
End Get
Set(value As Double)
_volume = Math.Round(value, 2)
End Set
End Property
End Class
Public Class calc2
Sub New()
'the constructor, recall the value from the instance (public) of the class 'Side' just built in the main thread
'but i don't understand why the instance it's nothing
_area = Form1.Side.Side^2
_volume = Form1.Side.Side^3
End Sub
Private _area As Double
Public Property area As Double
Get
Return Math.Round(_area, 2)
End Get
Set(value As Double)
_area = Math.Round(value, 2)
End Set
End Property
Private _volume As Double
Public Property volume As Double
Get
Return Math.Round(_volume, 2)
End Get
Set(value As Double)
_volume = Math.Round(value, 2)
End Set
End Property
End Class
Public Class c_Side
Sub New()
_Side = Form1.nudSide.Value
'_Side = Form1.rungetSide
End Sub
Private _Side As Double
Public Property Side As Double
Get
Return Math.Round(_Side, 2)
End Get
Set(value As Double)
_Side = Math.Round(value, 2)
End Set
End Property
End Class
내가 무엇을 찾고 있어요 것은 NumericUpDown
값을 메인 스레드에서 class_A
의 인스턴스를 생성하고 저장할 수 있으며, 별도의 스레드에서 (BackgroundWorker
)의 인스턴스를 생성 class_B
의 인스턴스에 저장하기 직전에 NumericUpDown
컨트롤의 값을 가져옵니다.
@SirRufo : 하나의 태그를 제거하는 것과 같이 사소한 편집을하지 마십시오. 특히 다른 사람이 실제로 게시물을 크게 개선하는 편집 작업을하는 비교적 새로운 게시물에 특히주의하십시오. 소식을 수정해야한다고 생각되면 수정이 필요한 _everything_을 수정하십시오. 그렇지 않으면 진행중인 편집을 중단하고 다시 편집해야합니다. –
미안 .. ?? 내 메시지를 편집하지 않아. – Marcello
'Form1.nudSide'. 한숨, VB.NET은 VB.NET 프로그래머가 스레드 된 코드를 제대로 작성할 수 없도록 설계되었습니다. 이 표현식은 작업자 스레드에서 호출 될 때 Form1 클래스의 * 새 인스턴스를 만듭니다. 작업자 스레드에서 UI 구성 요소에 절대 액세스하지 마십시오. bCalculate_Click()에서 올바르게 수행 한 방법에 유의하십시오. –