[VB.NET] Conflict met threading

Pagina: 1
Acties:

  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 30-01 09:38
De simpelste manier om een thread te starten is denk ik
Visual Basic .NET:
1
2
3
Dim t As Thread
t = New Thread(AddressOf MyClass.ThreadName)
t.Start()

Nou komt het voor dat de thread (ThreadName) meerdere keren vrijwel tegelijk wordt gestart. De thread loopt steeds tussen de 0 en ongeveer 60 seconden.
Ik dacht dat elke keer als de thread gestart wordt, dat deze zijn 'eigen' lokale variabelen gebruikt, maar ik heb toch regelmatig foutmeldingen zoiets als 'The connection was not closed. The connection's current state is open', of andere conflicten.
Het lijkt er dus op dat er conflicten met diverse objecten ontstaan.

Is hier een oplossing voor? Soms moet dezelfde thread wel 20 keer tegelijk worden uitgevoerd. (communicatie via tcpclient met diverse clients tegelijk)

[ Voor 4% gewijzigd door Swerfer op 02-11-2007 18:59 ]

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com


  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 14-05-2024

OZ-Gump

terug van weggeweest

Heb je de methode die in de thread gestart wordt (en de objecten die daarin weer gebruikt worden) wel threadsafe geimplementeerd? Zijn er geen (static) properties of methodes die gebruikt worden die misschien blijven hangen en dat soort zaken?

Kortom: iets meer (relevante) code kan veel meer inzicht bieden in je situatie.

[ Voor 8% gewijzigd door OZ-Gump op 02-11-2007 19:08 ]

My personal website


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 29-01 05:34

Gerco

Professional Newbie

Swerfer schreef op vrijdag 02 november 2007 @ 18:52:
Ik dacht dat elke keer als de thread gestart wordt, dat deze zijn 'eigen' lokale variabelen gebruikt
Dat is ook zo, maar jouw definitie van "lokaal" is waarschijnlijk niet helemaal correct:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
Public Class ThreadTest

  Dim someField As Integer ' NIET lokaal, want een field van de class
  Shared someSharedVar As Integer ' Deze is gedeeld tussen alle instances van je class

  Public Sub doSomething
    Dim someLocalVar As Integer ' Deze is wel lokaal

    ' Doe coole dingen
  End Sub
End Class 


Waarschijnlijk verwacht jij dat someField lokaal is per thread, maar dat is dus niet zo, alle Threads delen someField want deze bestaat per instance van je Class. De variabele someLocalVar is wel thread local, want die bestaat per invocatie van de Sub doSomething.

Shared variabelen zijn uiteraard al helemaal niet thread local, deze worden gedeeld door alle instances van je class. Om variabelen als someField en someSharedVar veilig te gebruiken in een multithreaded context, moet je synchroniseren (of locken in .NET dacht ik). De vb.net syntax daarvan ontgaat me alleen op het moment, dus daar kan ik geen voorbeeld van geven.

[ Voor 22% gewijzigd door Gerco op 02-11-2007 19:37 ]

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 30-01 09:38
OZ-Gump schreef op vrijdag 02 november 2007 @ 19:08:
Heb je de methode die in de thread gestart wordt (en de objecten die daarin weer gebruikt worden) wel threadsafe geimplementeerd? Zijn er geen (static) properties of methodes die gebruikt worden die misschien blijven hangen en dat soort zaken?

Kortom: iets meer (relevante) code kan veel meer inzicht bieden in je situatie.
De code is nogal lang en bevat teveel zaken die ik niet wil publiceren. Ik zal kijken of ik relevante stukken code waar het fout bij gaat in een volgende post kan plaatsen.

Als ik het goed begrijp, zouden er geen conflicten kunnen onstaan als bijvoorbeeld een datatable alleen in de thread wordt gebruikt en niet daarbuiten? Want het lijkt erop dat gegevens in de datatable door elkaar worden gehaald als er meerdere threads tegelijk lopen...
Visual Basic .NET:
1
2
3
4
5
6
7
8
        Dim DataTable As New DataTable("Mail")
        DataTable.Columns.Add("AccountName", System.Type.GetType("System.String"))
        DataTable.Columns.Add("ContactName", System.Type.GetType("System.String"))
        DataTable.Columns.Add("MailFrom", System.Type.GetType("System.String"))
        DataTable.Columns.Add("MailID", System.Type.GetType("System.String"))
        DataTable.Columns.Add("RcptTo", System.Type.GetType("System.String"))
        DataTable.Columns.Add("Domain", System.Type.GetType("System.String"))
        DataTable.Columns.Add("Send", System.Type.GetType("System.String"))

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com


  • Swerfer
  • Registratie: Mei 2003
  • Laatst online: 30-01 09:38
Gerco schreef op vrijdag 02 november 2007 @ 19:34:
[...]

Dat is ook zo, maar jouw definitie van "lokaal" is waarschijnlijk niet helemaal correct:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
Public Class ThreadTest

  Dim someField As Integer ' NIET lokaal, want een field van de class
  Shared someSharedVar As Integer ' Deze is gedeeld tussen alle instances van je class

  Public Sub doSomething
    Dim someLocalVar As Integer ' Deze is wel lokaal

    ' Doe coole dingen
  End Sub
End Class 


Waarschijnlijk verwacht jij dat someField lokaal is per thread, maar dat is dus niet zo, alle Threads delen someField want deze bestaat per instance van je Class. De variabele someLocalVar is wel thread local, want die bestaat per invocatie van de Sub doSomething.

Shared variabelen zijn uiteraard al helemaal niet thread local, deze worden gedeeld door alle instances van je class. Om variabelen als someField en someSharedVar veilig te gebruiken in een multithreaded context, moet je synchroniseren (of locken in .NET dacht ik). De vb.net syntax daarvan ontgaat me alleen op het moment, dus daar kan ik geen voorbeeld van geven.
Ik heb 1 object die public is in de gehele class, maar daar zit bijna zeker niet de fout in...
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Sub start()
...
        If Server.Pending Then
            Dim t As Thread
            t = New Thread(AddressOf CommClass.BlaBla)
            CommClass.Server = Server
            t.Start()
        End If
End Sub

Public Class CommClass

Public Server As TcpListener = Nothing

Sub BlaBla()
     Dim client As TcpClient = Server.AcceptTcpClient()
End Sub

Server is een TcpListener, die geef ik door aan de CommClass en daar haal ik een pending connection uit in Sub BlaBla...

Home Assistant | Unifi | LG 51MR.U44 | Volvo EX30 SMER+ Vapour Grey, trekhaak | SmartEVSE V3 | Cronos Crypto.com


  • barfieldmv
  • Registratie: Maart 2004
  • Laatst online: 10-10-2025
Volgens mij is die server nu een shared object over meerdere threads dat kan mis gaan.


De datatable die jij toonde kan absoluut niet door meerdere threads benaderd worden dat zal zeker ergens ooit een keer mis gaan.


ps. de code die je nu schrijft is zo generiek dat je je geen zorgen hoeft te maken over bijzondere code of bedrijfs gevoelige informatie. Laat gerust die BlaBla functie + uitwerking eens zien.

[ Voor 31% gewijzigd door barfieldmv op 02-11-2007 22:14 ]


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 27-01 19:30
Deze fout meldingen zeggen denk ik ook al iets:
Visual Basic:
1
'The connection was not closed. The connection's current state is open', of andere conflicten.


Elk thread probeerd je database te openen (terwijl die misschien al open is) en te sluiten.

Wanneer maak je connectie met je database en hoe geef je aan elk thread mee hoe/of ze de database kunnen gebruiken.

~ Mijn prog blog!

Pagina: 1