[VB-NET 2008] "Die Geister, die ich rief ..." - Threads beenden

07/02/2011 - 17:33 von Josef Morlo | Report spam
Hallo allerseits,

mir es zwar schon gelungen, den einen oder anderen Thread zur Aufgabe zu
bewegen ;-), aber beim unten zitierten Beispiel tappe ich völlig im
Dunkeln.

Ich erstelle mir die Threads („Bouncing Balls“) zwecks Datenübergabe über
eine eigene Klasse ‚ThreadData’ und starte die Threads vom UI-Thread aus.
Zum Beenden eines Threads setze ich ein StopRequested-Flag, mit dem die
Schleife verlassen werden kann.

Wenn ich die Anwendung beenden will, sind allerdings alle Threads noch
quicklebendig. - Wo liegt mein Denkfehler?

Danke für Tipps und Gruß

Josef Morlo

Code:
'Form1 mit Panel1, AddThread-, StopThread- und Exit-Button

Imports System.Drawing
Imports System.Threading
Public Class Form1
Private mData As ThreadData
Private mThreadList As New List(Of Thread)
Private mDataList As New List(Of ThreadData)

Private Class ThreadData
Private mShapeColor As Color
Private mRetardation As Integer = 15
Private mShapeSize As New Size(15, 15)
Private mGraphics As Graphics
Private mContainerColor As Color
Private mContainerSize As Size
Private mStopRequested As Boolean
Public WriteOnly Property StopRequested() As Boolean
Set(ByVal value As Boolean)
mStopRequested = value
End Set
End Property

Sub New(ByVal c As Color)
mShapeColor = c
mContainerColor = Form1.Panel1.BackColor
mContainerSize = Form1.Panel1.Size
mGraphics = Form1.Panel1.CreateGraphics

End Sub
Public Sub ThreadProc()

Dim shapes As Shape

shapes = New Circle(mShapeSize, _
mContainerSize, mShapeColor, _
mContainerColor, mRetardation)

While Not mStopRequested
shapes.DrawShapes(mGraphics)
End While

mGraphics.Dispose()
Thread.CurrentThread.Join()


End Sub
End Class

Private Sub btnAddThread_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnAddThread.Click
mData = New ThreadData(Color.Blue)
Dim th As New Thread(AddressOf mData.ThreadProc)
Thread.Sleep(500)
th.Start()
mThreadList.Add(th)
mDataList.Add(mData)
End Sub

Private Sub StopThread_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnStopThread.Click

Dim item As ThreadData
If mDataList.Count = 0 Then Return
item = mDataList.Item(mDataList.Count - 1)
item.StopRequested = True
mDataList.Remove(item)

End Sub

Private Sub btnExit_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnExit.Click
Dim i As Integer
For Each item As Thread In mThreadList
If item.IsAlive Then i = i + 1
Next
MsgBox(i.ToString & " " & "Alive")
End Sub
End Class

Public MustInherit Class Shape
Protected XVal As Integer = 0
Protected YVal As Integer = 0
Protected ShapeColor As Color
Protected DirectionY As Integer = 1
Protected DirectionX As Integer = 1
Protected ContainerSize As Size
Protected ContainerColor As Color
Protected mRetardation As Integer
Protected ShapeSize As Size

Public Sub New()
End Sub

Public MustOverride Sub DrawShapes(ByVal g As Graphics)

Protected Sub ComputePositions()
If (ContainerSize.Height - ShapeSize.Height - 1 < YVal) _
OrElse (YVal <= 0) Then
DirectionY = DirectionY * (-1)
End If

If (ContainerSize.Width - ShapeSize.Width - 1 < XVal) _
OrElse (XVal <= 0) Then
DirectionX = DirectionX * (-1)
End If
End Sub

End Class
Public Class Circle
Inherits Shape
Public Sub New(ByVal ss As Size, ByVal cs As Size, _
ByVal c As Color, ByVal cbc As Color, _
ByVal rtd As Integer)
MyBase.XVal = 0
MyBase.YVal = 0
ShapeColor = c
MyBase.ShapeSize = ss
MyBase.ContainerColor = cbc
MyBase.ContainerSize = cs
mRetardation = rtd
End Sub
Public Overrides Sub DrawShapes(ByVal g As Graphics)

Thread.Sleep(mRetardation)
g.DrawEllipse(New System.Drawing.Pen(ContainerColor), _
XVal, YVal, ShapeSize.Width, ShapeSize.Height)

SyncLock GetType(Thread)
XVal = XVal + MyBase.DirectionX
YVal = YVal + MyBase.DirectionY
MyBase.ComputePositions()
End SyncLock

g.DrawEllipse(New System.Drawing.Pen(ShapeColor), _
XVal, YVal, ShapeSize.Width, ShapeSize.Height)

End Sub
End Class
 

Lesen sie die antworten

#1 Armin Zingler
07/02/2011 - 18:48 | Warnen spam
Am 07.02.2011 17:33, schrieb Josef Morlo:
Hallo allerseits,

mir es zwar schon gelungen, den einen oder anderen Thread zur Aufgabe zu
bewegen ;-), aber beim unten zitierten Beispiel tappe ich völlig im
Dunkeln.

Ich erstelle mir die Threads („Bouncing Balls“) zwecks Datenübergabe über
eine eigene Klasse ‚ThreadData’ und starte die Threads vom UI-Thread aus.
Zum Beenden eines Threads setze ich ein StopRequested-Flag, mit dem die
Schleife verlassen werden kann.

Wenn ich die Anwendung beenden will, sind allerdings alle Threads noch
quicklebendig. - Wo liegt mein Denkfehler?



Thread.CurrentThread.Join()



Ohne diese Zeile dürfte es funktionieren. So wartet der Thread
unendlich bis er selbst beendet ist.


Armin

Ähnliche fragen