|
-
Jul 7th, 2017, 03:08 PM
#1
Thread Starter
Addicted Member
Custom class varables & multi-threading
I have a problem (so true..)
I have a program that uses several threads to get things done (simple enough).
However I recently discovered how to create my own class variables (*cheer*). So I decided to re-code my program to use these new variables (and thus cut huge chunks of extra code out). my problem is this.. I have a variable (Client) being "set" with a "new" statement inside a secondary thread (the cues to create it come from another computer via a port listener, and that part works fine), but when i try to access this variable outside the thread it responds as "nothing". this didn't happen before with basic variables (strings, Boolean, integers, etc) so I can only assume that I'm missing something really obvious in my class creation.
Can someone point me to the solution?
Code:
Namespace CardData
Public Class Card
Public Property Suit() As CardSuit
Get
Return m_Suit
End Get
Set
m_Suit = Value
End Set
End Property
Private m_Suit As CardSuit
Public Property Value() As CardValue
Get
Return m_Value
End Get
Set
m_Value = Value
End Set
End Property
Private m_Value As CardValue
Public Property Score() As Integer
Get
Return m_Score
End Get
Set
m_Score = Value
End Set
End Property
Private m_Score As Integer
Public ReadOnly Property DisplayValue() As String
Get
Return Suit.ToString() + " " + Value.ToString()
End Get
End Property
End Class
Public Class Client
Public Property PlayerHand() As List(Of Card)
Get
Return m_PlayerHand
End Get
Set
If Value.Equals(m_PlayerHand) Then Return
m_PlayerHand = Value
If IsNothing(m_PlayerHand) Then Return
PopulatePlayerCards()
End Set
End Property
Private m_PlayerHand As New List(Of Card)
Public Property PlayerSent() As List(Of Card)
Get
Return m_PlayerSent
End Get
Set
m_PlayerSent = Value
End Set
End Property
Private m_PlayerSent As New List(Of Card)
Public Property HostHand() As Played
Get
Return m_HostHand
End Get
Set
If Value.Equals(m_HostHand) Then Return
m_HostHand = Value
Client_Window.PopulateHostCards()
End Set
End Property
Private m_HostHand As New Played
Public Property Myturn As Boolean
Get
Return m_Myturn
End Get
Set
m_Myturn = Value
End Set
End Property
Private m_Myturn As Boolean = False
Public Property IPlayed As Boolean
Get
Return m_IPlayed
End Get
Set
m_IPlayed = Value
End Set
End Property
Private m_IPlayed As Boolean = False
Public Property Trade_Received As Boolean
Get
Return m_Trade_Received
End Get
Set
m_Trade_Received = Value
End Set
End Property
Private m_Trade_Received As Boolean = False
Private Sub SortHand()
Me.PlayerHand = PlayerHand.OrderBy(Function(x) x.Suit).ThenBy(Function(x) x.Value).ToList()
End Sub
Public Sub ShowHand()
SortHand()
For Each card In PlayerHand
Debug.Print([Enum].GetName(GetType(CardSuit), card.Suit) + " " + [Enum].GetName(GetType(CardValue), card.Value) + " ")
Next
End Sub
End Class
Public Class Played
Public Property Type() As HandType
Get
Return m_Type
End Get
Set
m_Type = Value
End Set
End Property
Private m_Type As HandType
Public Property Cards() As List(Of Card)
Get
Return m_Cards
End Get
Set
m_Cards = Value
End Set
End Property
Private m_Cards As List(Of Card)
Sub New(Optional CardList As List(Of Card) = Nothing, Optional HType As HandType = Nothing)
m_Type = HType
m_Cards = CardList
End Sub
End Class
End Namespace
-
Jul 7th, 2017, 03:23 PM
#2
Re: Custom class varables & multi-threading
I don't see any code regarding threads in what you posted. And there is no variable named 'Client'. There is a class named 'Client', but that is not a variable.
So I need to see more code before I can say anything.
But also beware this:
Code:
Client_Window.PopulateHostCards()
There are two reasons this line makes me upset.
The first is Forms don't play well with multiple threads. If the secondary thread can set the HostHand property, you need to do a little bit of work to make sure you do Form-oriented work on the main thread.
The second is I don't see a variable named 'Client_Window', so I know you're using the default instance of the form. Default instances play ESPECIALLY poorly with threads. Basically every thread gets its own instance, so if this line got called from the secondary thread, a new Client_Window form will be made and you'll operate on THAT, and not the one on the screen.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Jul 7th, 2017, 03:30 PM
#3
Thread Starter
Addicted Member
Re: Custom class varables & multi-threading
yes, that is the class i posted (that is used by the variable)
this is done is done inside a module (not the form)
Code:
Public GameData As CardData.Client
it gets "set" inside a thread (i'm not about to post the whole program) (located in the same module)
Code:
GameData = New CardData.Client
this part is in the "form"
but you can remove it. as i noted it runs fine, the issue comes later
Code:
Client_Window.PopulateHostCards()
my problem is after the thread is done. when i access "GameData", it's empty. = Nothing.
does that help?
-
Jul 7th, 2017, 04:42 PM
#4
Re: Custom class varables & multi-threading
The best explanation I can come up with, since I can't see your code, is that you have declared a more local variable named GameData that hides the more global one. So you set the local variable but don't set the global one. Here's an example of what that looks like, and yes it's legal:
Code:
Module Module1
Private GameData As GameData
Sub Main()
BadIdea()
If GameData Is Nothing Then
Console.WriteLine("Oh no!")
End If
End Sub
Private Sub BadIdea()
Dim GameData As GameData
GameData = New GameData()
End Sub
End Module
Public Class GameData
End Class
If that's the case, you can take some measures to not accidentally make the mistake again. Most VB developers follow special rules about how they capitalize their variables to help them understand if they're talking about something global, local, or a parameter. This makes it harder to accidentally access the wrong thing. Here's how I would have written the above:
Code:
Module Module1
Private _gameData As GameData
Sub Main()
BadIdea()
If _gameData Is Nothing Then
Console.WriteLine("Oh no!")
End If
End Sub
Private Sub BadIdea()
Dim gameData As New GameData()
_gameData = gameData
End Sub
End Module
Public Class GameData
End Class
In the conventions I use, "_gameData" has an underscore in front to help me remember it's part of the Module. So if I want to touch the module's variable and I didn't type an underscore, I know I did wrong. When I declared the local data, I used the lowercase "gameData" to help me remember it's a variable, not the type. The type is capitalized "GameData" to help me remember that it's "important". This gets a little wonky because I also capitalize properties. Some people follow the rule, "Never name a property the same thing as a class". I find that I don't tend to get as confused about that as I do in the cases that make the underscore needed.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Jul 7th, 2017, 05:02 PM
#5
Thread Starter
Addicted Member
Re: Custom class varables & multi-threading
It was a good theory (GameData being set in multiple locations), but it's only ever set (created) once.
I should clarify one thing (that may help). when i say GameData is empty when i try to access it after the thread runs that sets it, I am referring the the sub values. the GameData variable/object itself does contain all the sub variables, but they are all blank/empty/default states. this is why i think it's something i missed in the class creation code.. (OP), as the sub variables are all set and usable while in the thread. it's only when it exits the thread that they vanish.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|