Thread Priorität ändern

  • VB.NET

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Thread Priorität ändern

    Hallo,

    ich verwende die System.Threading.Thread Klasse

    Hier gibt es die Eigenschaft Priority
    .. ThreadPriority.Lowest - ThreadPriority.Highest


    Kannn ich diese Priorität ändern obwohl der Thread bereits gestartet ist und läuft.


    Also Problemstellung:
    Ich arbeite im Thread (ThreadPriority.Lowest) eine List ab.
    Jetzt ist es nur so, dass nach einigen Tagen die Liste anwächst und der Speicer überläuft.

    Als Lösung wurde ich den Thread auf Highest ändern sobald mehr wie 1000 Einträge in der Liste sind, anschließen wieder auf Lowest ändern.

    Quellcode

    1. If ListNewLogBuffer.Count > 1000 Then
    2. myThread.Priority = ThreadPriority.Highest
    3. Else
    4. myTestThread.Priority = ThreadPriority.Lowest
    5. End If


    Fragt sich nur ob das geht?

    signItUp1 schrieb:

    ob das geht?
    Berichte uns von Deinen praktischen Erfahrungen.
    1. Priorität rücklesen, nachdem Du sie geändert hast,
    2. Messung von Laufzeiten.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Jetzt ist es nur so, dass nach einigen Tagen die Liste anwächst und der Speicer überläuft.

    Als Lösung wurde ich den Thread auf Highest ändern sobald mehr wie 1000
    Einträge in der Liste sind, anschließen wieder auf Lowest ändern.


    Ich weiß nicht, ob ich einen Denkfehler habe, aber wie kommt man darauf, dass die Threadpriorität den Speicher leert?
    Für mich sieht es so aus, dass du immer weiter Objekte erstellst und den Speicher zumüllst, ohne diese wieder zu entfernen, wenn sie nicht mehr benötigt werden.
    Der Arbeitsspeicher ist schließlich nicht als Langzeitspeicher wie deine Festplatte gedacht, möglicherweise solltest du diese Liste mal auf die Festplatte speichern und nur Blockweise einlesen, was du gerade im Programm brauchst.
    @Counterbug Jou.
    @signItUp1 Wie befüllst Du die Liste?
    Wie entfernst Du Einträge, die abgearbeitet wurden?
    Wie groß ist ein Listenelement?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Also die Liste wird befüllt durch folgende Funktion befüllt:

    Quellcode

    1. Public Sub AddNewlogEntry(Time As DateTime, ByVal ThreadNumber As Integer, ByVal Message As String, ByVal LogLevel As SecsGemLib.DataDef.eSecsLogLevel)
    2. Try
    3. Dim tmpLog As sSECSGEMLOG
    4. If StopThread Then Exit Sub
    5. tmpLog.Time = Time
    6. tmpLog.ThreadNumber = ThreadNumber
    7. tmpLog.Message = Message
    8. tmpLog.LogLevel = LogLevel
    9. SyncLock ListNewLogBuffer
    10. ListNewLogBuffer.Add(tmpLog)
    11. End SyncLock
    12. Catch ex As Exception
    13. mod_ErrorFunctions.ShowErrorMessage("Error in " & Reflection.MethodInfo.GetCurrentMethod.Name & "(), Line: " & Err.Erl & vbCrLf & Err.Description & "ListNewLogBuffer.count:" & ListNewLogBuffer.Count, Me.ToString)
    14. End Try
    15. End Sub


    Ein Thread soll die gesamte Liste dann abarbeiten:

    Quellcode

    1. Private Sub WorkerThread()
    2. Try
    3. While Not StopThread
    4. If ListNewLogBuffer.Count > 0 Then
    5. ThreadNewlogEntry(ListNewLogBuffer)
    6. End If
    7. Thread.Sleep(1000)
    8. End While
    9. Catch ex As Exception
    10. If StopThread Then Exit Try
    11. mod_ErrorFunctions.ShowErrorMessage("Error in " & Reflection.MethodInfo.GetCurrentMethod.Name & "(), Line: " & Err.Erl & vbCrLf & Err.Description, Me.ToString)
    12. End Try
    13. End Sub


    Mein Gedankengang: Wenn die Priorität des Threads zu niedrig ist, kommt dieser nicht all zu oft dran, und somit befüllt sich die Liste schneller als sie abgearbeitet wird.

    Darum würde ich gerne ab 10000 Einträge die Priorität hochstellen

    signItUp1 schrieb:

    die Liste

    RodFromGermany schrieb:

    Wie entfernst Du Einträge, die abgearbeitet wurden?
    Rufst Du iwo ein .Remove() auf :?:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    signItUp1 schrieb:

    RemoveRange
    Hast Du Dich davon überzeugt, dass da alles, was aufgelaufen ist, beräumt wird?
    Müssen die Elemente ggf. .Dispose()d werden?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Denk ich schon:
    Die Elemente die in die Liste eingefügt werden sind ja lokale Variablen.

    Quellcode

    1. Public Sub AddNewlogEntry(Time As DateTime, ByVal ThreadNumber As Integer, ByVal Message As String, ByVal LogLevel As SecsGemLib.DataDef.eSecsLogLevel)
    2. Try
    3. Dim tmpLog As sSECSGEMLOG
    4. If _StopThread Then Exit Sub
    5. tmpLog.Time = Time
    6. tmpLog.ThreadNumber = ThreadNumber
    7. tmpLog.Message = Message
    8. tmpLog.LogLevel = LogLevel
    9. SyncLock ListNewLogBuffer
    10. ListNewLogBuffer.Add(tmpLog)
    11. End SyncLock
    12. Catch ex As Exception
    13. mod_ErrorFunctions.ShowErrorMessage("Error in " & Reflection.MethodInfo.GetCurrentMethod.Name & "(), Line: " & Err.Erl & vbCrLf & Err.Description & "ListNewLogBuffer.count:" & ListNewLogBuffer.Count, Me.ToString)
    14. ListOverflow()
    15. End Try
    16. End Sub

    signItUp1 schrieb:

    lokale Variablen
    Nö, denn ihre Instanz wurde der Liste übergeben.

    signItUp1 schrieb:

    VB.NET-Quellcode

    1. If _StopThread Then Exit Sub
    Diese Zeile als erstes nach dem Try.


    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    und die Liste wird dann wieder geleert (mit RemoveRange).

    Scheinbar kommen wir hier auf keinen grünen Zweig, eigentlich wollte ich wissen ob man die Thread Prioriät ändern kann wenn der Thread bereits gestartet wurden.

    Im Programm gibt es ja diverse Threads die in die Liste hineinschreiben.
    Ein Thread soll die Liste dann abarbeiten (in ein File schreiben).

    Wenn aber der Thread, der die Liste abarbeitet nicht oft genug an den Zug kommt -> dann wächst die Liste immer weiter und weiter.
    Darum wollte ich die Priorität des Threads erhöhen sobald mehr als 1000 Einträge in der Liste sind. Wenn die Liste wieder entleert ist, hätte ich die Priorität wieder auf Lowest zurückgestellt.

    signItUp1 schrieb:

    eigentlich wollte ich wissen
    warum Dein Speicher überläuft.
    Die Threadpriorität ist sekundär.
    ========
    Da war noch eine Frage offen:

    RodFromGermany schrieb:

    Wie groß ist ein Listenelement?



    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Also ein Element beinhaltet

    Quellcode

    1. Public Structure sLOGITEM
    2. Dim Time As DateTime
    3. Dim ThreadNumber As Integer
    4. Dim Message As String
    5. Dim LogLevel As Integer
    6. End Structure


    Die Message ist auf 100 Zeichen begrenzt
    Also ich weiß jetzt nicht genau wie groß ein DateTime Element ist.
    Aber es werden so ca. 150Byte-200Byte sein

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „signItUp1“ ()

    signItUp1 schrieb:

    Structure
    Ist Pillepalle, 1000 Instanzen davon machen nix, das Problem hat andere Ursachen.
    Mach da mal ne Class draus und leg die Elemente mit New an.
    ----
    Vielleicht machst Du ein kleines Testprojekt, das Deinen Effekt reproduziert, das häng dran (ersatzweise Dein komplettes Projekt).
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Aso, also mit 1000 Elementen wollte nur ich einmal Testweiße arbeiten und schaun wie es sich verhält.

    Das Problem selber tritt erst bei ca. 8 000 000 Elementen auf. Also nach ca. 10Tagen Programmlaufzeit hat sich die Liste soweit aufgebaut.
    Aber eigentlich sollte sie sich gar nicht aufbauen sondern gleich schnell wieder abgearbeitet werden wie sie aufgebaut wird.

    Aber gut, ich mach mal eine

    VB.NET-Quellcode

    1. CLASS
    statt der

    VB.NET-Quellcode

    1. STRUCTURE

    signItUp1 schrieb:

    10Tagen
    Pack mal nach 100 "Entnahmen" ein GC.Collect() in den Code.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    na, dann ist ja alles geklärt.

    Eigentümlich - ich hab nämlich ühaupt keine klare Problembeschreibung gefunden in diesem Thread.
    Am Ende klang es nach dem klassischen Producer-Consumer-Problem, bei dem der eine Thread Daten "produziert", und ein anderer die Daten verarbeiten soll.
    Für solch gäbe es ganz fabelhafte Standard-Lösungen in vb.net, aber nun, da alles

    :thumbup:

    wohl nicht mehr relevant.