Smaltimento di una spazzola statica
-
19-08-2019 - |
Domanda
Sto scrivendo un'app di bioritmo. Per provarlo ho un modulo con un pulsante e un PictureBox. Quando faccio clic sul pulsante lo faccio
myPictureBox.Image = GetBiorhythm2();
Che funziona bene per la prima volta, ma al secondo clic provoca la seguente eccezione:
System.ArgumentException: Parameter is not valid.
at System.Drawing.Graphics.CheckErrorStatus
at System.Drawing.Graphics.FillEllipse
at Larifari.Biorhythm.Biorhythm.GetBiorhythm2 in c:\delo\Horoskop\Biorhythm.cs:line 157
at Larifari.test.Button1Click in c:\delo\Horoskop\test.Designer.cs:line 169
at System.Windows.Forms.Control.OnClick
at System.Windows.Forms.Button.OnClick
at System.Windows.Forms.Button.OnMouseUp
at System.Windows.Forms.Control.WmMouseUp
at System.Windows.Forms.Control.WndProc
at System.Windows.Forms.ButtonBase.WndProc
at System.Windows.Forms.Button.WndProc
at ControlNativeWindow.OnMessage
at ControlNativeWindow.WndProc
at System.Windows.Forms.NativeWindow.DebuggableCallback
at ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop
at ThreadContext.RunMessageLoopInner
at ThreadContext.RunMessageLoop
at System.Windows.Forms.Application.Run
at Larifari.test.Main in c:\delo\Horoskop\test.cs:line 20
la funzione di riduzione che causa l'errore è:
public static Image GetBiorhythm2() {
Bitmap bmp = new Bitmap(600, 300);
Image img = bmp;
Graphics g = Graphics.FromImage(img);
Brush brush = Brushes.Black;
g.FillEllipse(brush, 3, 3, 2, 2); //Here the exception is thrown on the second call to the function
brush.Dispose(); //If i comment this out, it works ok.
return img;
}
se commento lo smaltimento dei pennelli funziona bene, ma non sono contento di questo e desidero trovare una soluzione alternativa. Potete aiutarmi per favore?
Soluzione
Sembra che tu stia cercando di smaltire un elemento statico, che causa alcuni problemi la prossima volta che viene utilizzato:
Brush brush = Brushes.Black;
g.FillEllipse(brush, 3, 3, 2, 2); //Here the exception is thrown on the second call to the function
brush.Dispose(); //If i comment this out, it works ok.
Quando si imposta brush = Brushes.Black, in realtà si imposta il pennello come riferimento (o puntatore) su Brushes.Black statico. Eliminandolo, stai effettivamente scrivendo:
Brushes.Black.dispose();
Quando torni a utilizzare nuovamente il pennello nero, il runtime dice che non puoi perché è già stato eliminato e non è un argomento valido per g.FillEllipse ()
Un modo migliore per scrivere questo potrebbe essere semplicemente:
g.FillEllipse(Brushes.Black, 3, 3, 2, 2);
Oppure, se vuoi essere davvero complesso al riguardo:
Brush brush = Brushes.Black.Clone();
g.FillEllipse( brush, 3, 3, 2, 2 );
brush.Dispose();
O se non ti interessa che le cose sembrino sbagliate, commenta semplicemente il pennello.Dispose (); riga nel codice originale.
Altri suggerimenti
Bruhes.Black è una risorsa di sistema e non è destinata a essere smaltita. Il runtime gestisce i pennelli nella classe Pennelli, Penne e altri oggetti simili. Crea e dispone quegli oggetti come richiesto, mantenendo in vita gli oggetti utilizzati di frequente in modo da non doverli creare e distruggere continuamente.
La documentazione per la classe Brushes dice:
La classe Brushes contiene statico proprietà di sola lettura che restituiscono a Pennello oggetto del colore indicato da il nome della proprietà. Di solito lo fai non è necessario disporre esplicitamente di pennello restituito da una proprietà in questo classe, a meno che non sia usato per costruire un nuovo pennello.
In breve, non chiamare Dispose sugli oggetti forniti dal sistema.
Non penso che tu debba chiamare. Disporre su pennelli statici, solo se ne crei di nuovi. Sebbene, personalmente, userei la sintassi usando .. cioè:
using (Brush brush = new SolidBrush(...))
{
g.FillEllipse(brush, 3, 3, 2, 2);
}
E probabilmente dovresti fare la stessa cosa con l'oggetto grafico che crei.