Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    [VB2010 WinForm] problema in un classe personale con immagine da disco

    buongiorno,

    ho costruito queste due classi per gestire le manutenzioni di un mezzo...funziona alla grande, l'unico problema non capisco com'è possibile nonostante elimini l'oggetto un oggetto, l'immagine su disco precedentemente associata all'oggetto (classe) continua ad essere in uso dal programma fino a quando non chiudo completamente il programma..

    gli oggetti sono contenuti da un List(of OggettoManutenzione) pubblico

    Public Manutenzioni As New List(Of OggettoManutenzione)

    queste le due classi, in particolare da prendere in cosiderazione la seconda che gestisce l'immagine (TipoImmagineMan):

    codice:
    Public Class OggettoManutenzione
        Class EventoManutenzione
            Private _KM As Long = Nothing
            Private _Data As Date = Nothing
            Private _Mesi As Long = Nothing
            Private _Nota As String = Nothing
            Private _Costo As Double
            Public Property KM As Long
                Get
                    KM = _KM
                End Get
                Set(ByVal value As Long)
                    _KM = value
                End Set
            End Property
            Public Property Data As Date
                Get
                    Data = _Data
                End Get
                Set(ByVal value As Date)
                    _Data = value
                    _Mesi = Nothing
                End Set
            End Property
            Public Property Mesi As Long
                Get
                    Mesi = _Mesi
                End Get
                Set(ByVal value As Long)
                    _Mesi = value
                    _Data = Nothing
                End Set
            End Property
            Public Property Nota As String
                Get
                    Nota = _Nota
                End Get
                Set(ByVal value As String)
                    _Nota = value
                End Set
            End Property
            Public Property Costo As Double
                Get
                    Costo = _Costo
                End Get
                Set(ByVal value As Double)
                    _Costo = value
                End Set
            End Property
            Sub Setta(ByVal KM As Long, ByVal Mesi As Long)
                _KM = KM
                _Mesi = Mesi
            End Sub
    
        End Class
    
        Private _ID As Long = 0
        Private Shared _Conta As Long = 0
        Private _Dettagli As String = Nothing
        Public Image As TipoImmagineMan = Nothing
        Private _Voce As String = Nothing
        Private _Manutenzioni As New List(Of EventoManutenzione)
        Private _Intervallo As New EventoManutenzione
    
        Public ReadOnly Property ID As Long
            Get
                ID = _ID
            End Get
        End Property
        Public Property Dettagli As String
            Get
                Dettagli = _Dettagli
            End Get
            Set(ByVal value As String)
                _Dettagli = value
            End Set
        End Property
        Public Property Voce As String
            Get
                Voce = _Voce
            End Get
            Set(ByVal value As String)
                _Voce = value
            End Set
        End Property
        Public Property Manutenzioni As List(Of EventoManutenzione)
            Get
                Manutenzioni = _Manutenzioni
            End Get
            Set(ByVal value As List(Of EventoManutenzione))
                _Manutenzioni = value
            End Set
        End Property
        Public Property Intervallo As EventoManutenzione
            Get
                Intervallo = _Intervallo
            End Get
            Set(ByVal value As EventoManutenzione)
                _Intervallo = value
            End Set
        End Property
    
        Sub New()
            _Conta += 1
            _ID = _Conta
        End Sub
    
    End Class
    
    Public Class TipoImmagineMan
        Private _Image As Image = My.Resources.NoImage
        Private _PosizImage As String = Nothing
    
        Public Property Image As Drawing.Bitmap
            Get
                Image = _Image
            End Get
            Set(ByVal value As Drawing.Bitmap)
                _Image = IIf(Not IsNothing(value), value, My.Resources.NoImage)
            End Set
        End Property
        Public Property Strings As String
            Get
                Strings = _PosizImage
            End Get
            Set(ByVal value As String)
                Image = TipoImmagineMan.GetImage(value)
                _PosizImage = value
            End Set
        End Property
    
        Shared Function GetImage(ByVal ImgPosiz As String) As Image
            Dim ImagePos As String = EstrapolaStringa(ImgPosiz, , ",")
            Dim ImageLink As String = EstrapolaStringa(ImgPosiz, ",")
            Try
                Select Case ImagePos
                    Case "File"
                        Return System.Drawing.Image.FromFile(ImageLink)
                    Case "Default" ' --> My.Resource
                        Return My.Resources.ResourceManager.GetObject(ImageLink)
                    Case Else
                        Return Nothing
                End Select
            Catch ex As Exception
                Return Nothing
            End Try
        End Function
    
    End Class
    se non si capisce molto proverò a spiegare l'essenziale..
    sono accettati anche consigli
    Michele

  2. #2
    Un oggetto viene eliminato dalla memoria (e va nel garbage collector) quando nel programma non esistono più riferimenti a quell'oggetto. Nel tuo caso credo che il problema sia da ricercarsi nei vari metodi/proprietà Shared che hai dichiarato nella classe principale. Mi riferisco, in particolare, alla variabile _Conta. Dichiararla come shared è a mio avviso errato, in quanto l'istanza di questa variabile rimarrà in memoria anche quando tenterai di distruggere l'oggetto che la contiene.
    Chi non cerca trova.

  3. #3
    quindi mi tiene in piedi ogni nuovo oggetto che viene creato..
    provo a toglierla temporaneamente ...se il problema è questo, proverò qualcosaltro che mi dia l'ID (quell'id mi serve per avere l'ordine cronologico della creazione dell'oggetto)
    Michele

  4. #4
    ho fatto quella prova, ma niente...

    ho anche provato a cambiare immagine per un oggetto che utilizza immagine da disco (dandogli = Nothing mi carica una immagine di default da my.resource, quindi dovrebbe liberare la precedente istanza immagine)

    codice:
    Manutenzioni(2).Image.Image = nothing
    ma quella sostituita risulta sempre in uso, pur non essendo più usata da nulla
    Michele

  5. #5
    Su MSDN si legge:
    The file remains locked until the Image is disposed.

    Di conseguenza non è sufficiente assegnare il valore Nothing, ma dovresti scrivere qualcosa del genere:
    codice:
    Manutenzioni(2).Image.Image.Dispose()
    Il discorso di prima sulle proprietà shared rimane ancora valido, anche se in questo caso non era la causa del problema (ma eventualmente la causa di altri problemi).
    Ti posto un esempio (semplificato) di come potresti evitare la variabile shared:
    codice:
    Public Class Mezzo
        Public Property KM As Integer
        Public Property Data As Date
        Public Property Mesi As Integer
        Public Property Nota As String
        Public Property Costo As Decimal
        Public Property ID As Integer
    End Class
    
    Public Class Mezzi
        Inherits List(Of Mezzo)
    
        Private contatore As Integer = 0
    
        Public Overloads Sub Add(m As Mezzo)
            contatore += 1
            m.ID = contatore
        End Sub
    End Class
    Chi non cerca trova.

  6. #6
    grande Tas... problema risolto.. per automatizzare la cosa, l'ho aggiunta nella proprietà della classe TipoImmagineMan e funge bene per adesso.

    codice:
        Public Property Image As Drawing.Bitmap
            Get
                Image = _Image
            End Get
            Set(ByVal value As Drawing.Bitmap)
                _Image.Dispose()
                _Image = IIf(Not IsNothing(value), value, My.Resources.NoImage)
            End Set
        End Property
    poi mi hai dato uno spunto ...avrei dovuto arrivarci prima o poi per altri motivi all'esempio di Inherits List(Of Mezzo) che hai postato

    quindi se volessi automatizzare il dispose alla eliminazione dell'oggetto, dovrei aggiungere quale sub alla Inherits List(Of Mezzo)

    percaso si chiama "Remove" ed è valida se chiamo "RemoveAt" e anche "Remove" ? o ne devo creare per ognuna

    grazie ancora
    Michele

  7. #7
    Remove e RemoveAt sono due metodi diversi, pertanto dovresti fare l'overloads di entrambi. Tuttavia ti puoi limitare ad implementare i metodi che utilizzi nel tuo progetto.
    Chi non cerca trova.

  8. #8
    immaginavo...comunque per adesso solo RemoveAt ...ho riorganizzato il mio progetto con la nuova classe ereditata...e va alla grande..
    unica cosa ho dovuto rendere Public _ID nella classe OggettoManutenzione altrimenti mi dava errore di accesso.. io voglio che l'_ID sia in sola lettura (di Fatti la Proprietà è read only, ma se rendo pubblico _ID non serve a molto) .. è possibile si , ma adesso non ricordo quael'era la dichiarazione per essere ereditata privatamente ?

    codice:
    Public Class Manu
        Inherits List(Of OggettoManutenzione)
    
        Private contatore As Integer = 0
    
        Public Overloads Sub Add(ByVal m As OggettoManutenzione)
            contatore += 1
            m._ID = contatore
            MyBase.Add(m)
        End Sub
        Public Overloads Sub RemoveAt(ByVal Index As Integer)
            Me.Item(Index).Image.Image.Dispose()
            MyBase.RemoveAt(Index)
        End Sub
    Michele

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.