2.841 messaggi dal 28 gennaio 2003
Pensavo che using fosse un modo diverso di scrivere Try-Finally, ma sono incappato nel mio codice che con using va in errore, mentre funziona con Try-Finally. Il codice di sotto è sintetizzato al massimo. Ho questa procedura

Protected Sub Resize(ByRef bmp As Bitmap, ByVal width As Integer)
  'creo una nuova Bitmap
  Dim b As Bitmap = DirectCast(bmp.Clone(), Bitmap)
  'chiudo bmp altrimenti rimane sempre "in uso" e non si può modificare
  bmp.Dispose()

  'restituisco la nuova Bitmap, che ho passato per riferimento
  bmp = b
End Sub


Nella realtà, leggo una immagine da disco, la passo alla procedura per essere ridimensionata, creo una nuova immagine ridimensionata o modificata, faccio il dispose della immagine passata perchè non sia sempre in uso, restituisco nella variabile passata per riferimento la nuova immagine.
Ebbene, questo codice funziona
Dim bmp As Bitmap = Nothing

Try
  bmp = New Bitmap(500, 500)
  Resize(bmp, 100)
  bmp.Save("c:\tmp\tmp.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
Finally
  bmp.Dispose()
End Try


mentre questo no
Using bmp As New Bitmap(500, 500)
  Resize(bmp, 100)
  bmp.Save("c:\tmp\tmp.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
End Using


errore nella riga
bmp.Save("c:\tmp\tmp.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)

System.ArgumentException: Parametro non valido.


Mi potete aiutare a capire dove sbaglio?

Ciao

Pietro
come hai sperimentato non sono la solita cosa, il blocco using richiama automaticamente il metodo Dispone nell'oggetto che istanzi nella sua dichiarazione.

il blocco using non esclude la necessità di intercettare gli errori

ciao marco

Chi parla senza modestia troverà difficile rendere buone le proprie parole.
Confucio

http://nostromo.spaces.live.com/default.aspx
Ciao Pietro,

occhio che stai commettendo un errore MOOOOOOOLTO subdolo

Nel tuo esempio fai una cosa parecchio strana, perché invochi la dispose dell'istanza originale all'interno del metodo Resize, e passando l'argomento per riferimento, provi a SOSTITUIRE il riferimento di bmp alla nuova immagine clonata.

Se questo è assolutamente lecito nel blocco try..finally, lo stesso non può dirsi per il blocco Using. Infatti quando istanzi una variabile locale tramite un blocco Using, essa è readonly all'interno del blocco. Ciò significa che non puoi assegnarle un'altra istanza di oggetto. Il compilatore C# solleva un errore in casi come questo, dicendoti che la "local variable è readonly". Il compilatore VB è invece molto più permissivo, ma a runtime ignora l'assegnamento che fai dentro Resize anche se hai passato l'argomento per riferimento.

Te ne puoi accorgere facilmente modificando un il codice in questo modo:
Dim b As Bitmap
Protected Sub Resize(ByRef bmp As Bitmap, ByVal width As Integer)
'creo una nuova Bitmap
b = DirectCast(bmp.Clone(), Bitmap)
'chiudo bmp altrimenti rimane sempre "in uso" e non si può modificare
bmp.Dispose()

'restituisco la nuova Bitmap, che ho passato per riferimento
bmp = b
End Sub

e poi usando Debug.Assert per verificare che fine fanno le istanze:
Dim bmp As Bitmap = Nothing

Try
bmp = New Bitmap(500, 500)
Resize(bmp, 100)
Debug.Assert(b.Equals(bmp))
bmp.Save("c:\tmp\tmp.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
Finally
bmp.Dispose()
End Try

e
Using bmp As New Bitmap(500, 500)
Resize(bmp, 100)
Debug.Assert(b.Equals(bmp))
bmp.Save("c:\tmp\tmp.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
End Using


Sai qual è il risultato? che il secondo Debug.Assert fallisce, perché bmp è rimasta quella di prima.

In ultima analisi, l'argument exception che ottieni è causata dal fatto che stai provando a fare il Save di un bitmap disposed (perchè hai invocato Disposed dentro resize).

Morale della favola: Using e try...finally sono simili, MA NON ESATTAMENTE UGUALI

Ciao!
2.841 messaggi dal 28 gennaio 2003
Ti ringrazio davvero per la spiegazione.
Purtroppo, la procedura citata utilizza la bmp passata, ma ne crea un'altra.
Ho preferito distruggere l'originale e sostituirla con la nuova, passando il parametro per riferimento, e in effetti va.

ciao

Pietro

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.
In primo piano

I più letti di oggi

Media
In evidenza
MISC