Jeter une brosse statique
-
19-08-2019 - |
Question
J'écris une application de biorythme. Pour le tester, j'ai un formulaire avec un bouton et un PictureBox. Quand je clique sur le bouton, je fais
myPictureBox.Image = GetBiorhythm2();
Ce qui fonctionne pour la première fois, mais lors du deuxième clic , l'exception suivante est générée:
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 fonction de coupure à l'origine de l'erreur est:
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;
}
si je commente l'élimination des brosses, cela fonctionne bien, mais je ne suis pas satisfait de cela et souhaite trouver une solution alternative. Pouvez-vous m'aider s'il vous plaît?
La solution
On dirait que vous essayez de vous débarrasser d'une statique, ce qui pose quelques problèmes lors de sa prochaine utilisation:
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.
Lorsque vous définissez brush = Brushes.Black, vous définissez brush en tant que référence (ou pointeur) sur la valeur statique Brushes.Black. En le disposant, vous écrivez effectivement:
Brushes.Black.dispose();
Lorsque vous utilisez de nouveau le pinceau noir, le moteur d'exécution vous dit que vous ne pouvez pas le supprimer car il a déjà été supprimé et que l'argument n'est pas valide pour g.FillEllipse ()
Une meilleure façon d'écrire ceci pourrait être simplement:
g.FillEllipse(Brushes.Black, 3, 3, 2, 2);
Ou, si vous voulez être vraiment complexe à ce sujet:
Brush brush = Brushes.Black.Clone();
g.FillEllipse( brush, 3, 3, 2, 2 );
brush.Dispose();
Ou si vous ne vous souciez pas des choses qui ne vont pas bien, commentez simplement brush.Dispose (); ligne dans votre code d'origine.
Autres conseils
Bruhes.Black est une ressource système et ne vous est pas destiné. Le moteur d'exécution gère les pinceaux de la classe Pinceaux, les stylos et d'autres objets similaires. Il crée et élimine ces objets selon les besoins, en conservant en vie les objets fréquemment utilisés, de sorte qu'il ne soit pas obligé de les créer et de les détruire en permanence.
La documentation de la classe Brushes indique:
La classe Brushes contient static propriétés en lecture seule qui retournent un Pinceau objet de la couleur indiquée par le nom de la propriété. Vous faites généralement ne pas avoir à disposer explicitement de la brosse retournée par une propriété dans cette classe, sauf si elle est utilisée pour construire un nouveau pinceau.
En bref, n'appelez pas Dispose sur les objets fournis par le système.
Je ne pense pas que vous deviez appeler .Dispose sur les pinceaux statiques, uniquement si vous en créez de nouveaux. Personnellement, j’utiliserais la syntaxe using .. ie:
using (Brush brush = new SolidBrush(...))
{
g.FillEllipse(brush, 3, 3, 2, 2);
}
Et vous devriez probablement faire la même chose avec l'objet graphique que vous créez.