Announcement

Collapse
No announcement yet.

MVC - Model PropertiesChanged Vorhandener Quellcode zu Performancelastig

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • MVC - Model PropertiesChanged Vorhandener Quellcode zu Performancelastig

    Moin, Moin!

    Ich habe ein Problem.

    Und zwar würde ich gerne MVC-Pattern anwenden und habe dabei immer öfter das Problem,
    dass ich eine Event, wie OnChange, gerne in einem Model hätte.

    Dazu soll die Klasse des Model's ganz klassisch aussehen.
    Mit aussnahme, dass diese von einer anderen Klasse erbt. (MyFramework.DataType.Model)

    Klasse: MeinProgramm.Kunde
    Code:
    Namespace meinProgramm
     
     Class Kunde
         Inherits MyFramework.DataType.Model
     
       Public Property Vorname As String
       Public Property Nachname As String
       'usw.....
     
     End Class
     
    End Namespace
    Klasse: MyFramework.DataType.Model
    Code:
    Namespace MyFramework.DataType
     
     Public Class Model
            Inherits EventArgs
     
            Private WithEvents myTimer As New Timer
            Private _checkValString As String = ""
     
            Public Sub New()
                myTimer.Start()
                myTimer.Interval = 5000
            End Sub
     
            ''// EVENTS
            Private Event OnChanged As EventHandler(Of Model)
     
            '' // Functions
     
            Private Sub checkValuesChanged(ByVal sender As System.Object, ByVal e _
              As System.EventArgs) Handles myTimer.Elapsed
    
                Dim _modelType As Type = Me.GetType
                Dim _modelPropertiesInfo() As PropertyInfo = _
                  _modelType.GetProperties()
    
                Dim _newCheckString As String = ""
    
                For i = 0 To _modelPropertiesInfo.Length - 1
    
                    _newCheckString = _newCheckString & _modelPropertiesInfo( _
                      i).GetValue(Me, Nothing)
    
                Next
    
                If _newCheckString <> _checkValString Then
    
                    _checkValString = _newCheckString
                    RaiseEvent OnChanged(New Object, Me)
    
                End If
    
            End Sub
     
        End Class
     
    End Namespace
    Das ganze funktioniert auch einwandfrei.
    Nur ist es leider viel zu performance lastig.
    Hat hier vielleicht irgend jemand eine Idee, wie ich das Problem
    besser lösen kann?


    Ich hoffe ich konnte einigermaßen erklären, worauf ich hinaus möchte und habe
    das ganze nicht unendlich falsch im Forum positioniert und/oder betitelt.

    Vielen Dank!

  • #2
    Das mit einem Timer zu machen erscheint mir auch sehr merkwürdig Der OnChanged Aufruf gehört in den Setter der Property.

    Edit : Für das übliche Vorgehen sie dir auch das INotifyPropertyChanged Interface an.

    Edit2 : Model ist bei dir ein EventArgs

    Comment


    • #3
      Stimmt geht auch Ohne

      Dann muss ich nur folgende Zeile wie Folgt ändern
      Code:
      Private Event OnChanged As EventHandler(Of Model) -> Private Event OnChanged As EventHandler(Of EventArgs)
      Gibt es in VB.Net die möglichkeit, abzufangen, wenn AddHandler auf das Object ausgeführt wird und dann erst den Timer zu starten?
      Wäre zumindest nicht ganz so Performancelastig.

      "INotifyPropertyChanged" gibt leider nicht her, was ich benötige. Ich möchte umgehen, dass in jedem Setter das Event ausgeführt wird oder eine Funktion aufgerufen wird,
      in der dann das Event ausgeführt wird.

      Comment


      • #4
        Meine Vorerst letzte Variante:
        Code:
        Namespace MyFramework.DataType
         
            Public Class Model
        
                Private WithEvents myTimer As Timer
                Private _checkValString As String = ""
        
                ''// EVENTS
                Private _events As EventHandlerList = Nothing
                Protected ReadOnly Property Events() As EventHandlerList
                    Get
                        If _events Is Nothing Then
                            _events = New EventHandlerList()
                        End If
                        Return _events
                    End Get
                End Property
        
                Public Custom Event OnChanged As EventHandler
        
                    AddHandler(ByVal value As EventHandler)
        
                        myTimer = New Timer
                        myTimer.Start()
                        myTimer.Interval = 500
        
                        Me.Events.AddHandler("OnChanged", value)
                    End AddHandler
        
                    RemoveHandler(ByVal value As EventHandler)
        
                        myTimer.Stop()
                        Me.Events.RemoveHandler("OnChanged", value)
        
                    End RemoveHandler
        
                    RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
                        CType(Me.Events("OnChanged"), EventHandler).Invoke(sender, e)
                    End RaiseEvent
        
                End Event
        
                '' // Functions
        
        
        
                Private Sub checkValuesChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles myTimer.Elapsed
                    Dim _newCheckString As String = getNewCheckString()
                    If _newCheckString <> _checkValString Then
                        _checkValString = _newCheckString
                        RaiseEvent OnChanged(New Object, New EventArgs)
                    End If
                End Sub
        
                Private Function getNewCheckString() As String
                    Dim _modelType As Type = Me.GetType
                    Dim _modelPropertiesInfo() As PropertyInfo = _modelType.GetProperties()
                    Dim _newCheckString As String = ""
                    For i = 0 To _modelPropertiesInfo.Length - 1
                        _newCheckString = _newCheckString & _modelPropertiesInfo(i).GetValue(Me, Nothing)
                    Next
                    Return _newCheckString
                End Function
        
                Public Function ToArray() As Array
        
                    Dim _modelType As Type = Me.GetType
                    Dim _modelPropertiesInfo() As PropertyInfo = _modelType.GetProperties()
                    Dim _returnArray() As Object
        
                    For i = 0 To _modelPropertiesInfo.Length - 1
                        ReDim Preserve _returnArray(i)
                        _returnArray(i) = _modelPropertiesInfo(i).GetValue(Me, Nothing)
                    Next
        
                    Return _returnArray
        
                End Function
        
            End Class
        
        End Namespace
        Wenn jemand eine bessere lösung hat, wäre ich dankbar!!

        Comment


        • #5
          Gibt es in VB.Net die möglichkeit, abzufangen, wenn AddHandler auf das Object ausgeführt wird und dann erst den Timer zu starten?
          Wäre zumindest nicht ganz so Performancelastig.
          Hab ich nur in C# schonmal gemacht aber geht bestimmt auch in VB einfach Add- und RemoveHandler zu überschreiben um dann den Timer da zu starten bzw. zu stoppen.

          Ich möchte umgehen, dass in jedem Setter das Event ausgeführt wird oder eine Funktion aufgerufen wird,
          in der dann das Event ausgeführt wird.
          Ist deine Entscheidung. Entweder du implementierst den EventAufruf in jedem Setter oder nur da wo du es braucht. Per Timer wird das aber mit hoher Wahrscheinlichkeit immer performancelastig sein und du bekommst den Changed Event immer asynchron. Was passiert wenn du die gleiche Property mehrmals änderst zwischen zwei TimerEvents? Ist das immer richtig wenn du dann nur einmal den Changed Event bekommst? Was ist wenn du mehrere Properties änderst? In welcher Reihenfolge bekommst du die Changed Events der Änderungen? Bestimmt nicht in der Reihenfolge wie du sie geändert hast. Das Verhalten per Timer wäre mir zu speziell und nur sehr eingeschränkt zu gebrauchen.

          Wenn es dir zuviel Aufwand bedeutet das in jedem Setter zu machen würde ich mir da eher Erleichterungen beim Implementieren ausdenken (Code generatoren, Codesnippets, irgendwas aus der AOP Ecke) als das über einen Timer zu lösen.


          Edit: Dein Code ist problematisch. Füg mal zwei EventHandler hinzu und nimm nur einen Weg. Du solltest den Timer nur erzeugen wenn noch keiner da ist und das Anhalten nur machen wenn alle Handler abgehängt wurden.

          Comment


          • #6
            Ok, überzeugt.

            Alles kacka und ich nutze lieber einen Codegenerator.

            Ist glaube ich besser so.

            Vielen Dank für die Antworten.

            Comment


            • #7
              Ich hätte mich nicht so ausgedruckt aber deine Entscheidung unterstütze ich absolut

              Comment


              • #8
                Gerade beim MVC Pattern gibt es oft sehr viel Verwirrung. Das Pattern ist schon relativ alt und in Zeiten von DataBinding eigentlich auch schon nicht mehr aktuell. Pures MVC verlangt eigentlich das DataBinding selbst zu lösen. Meistens fährt man mit einem Pattern wie MVVM oder so wesentlich besser bzw. passt es viel besser auf aktuelle Technologien. Man hat ein ViewModel was alle Eigenschaften öffentlich zum DataBinding freigibt, der View bindet sich daran und das ViewModel gibt die Änderungen an das Model weiter. So ist es in sehr vielen UI Frameworks in eigentlich egal welcher Programmiersprache gelöst (paradoxerweise nennen sich manche Frameworks trotzdem noch MVC)

                Comment

                Working...
                X