|
Okay, I’m confused on what to Dispose and when. Below is a subroutine called from a loop. First time through it is okay, the second time through it throws a System.Exception “Parameter is not valid” on the DrawString line. But if I remove all the Dispose commands at the bottom I can call this subroutine a dozen times without error.
Obviously in this instance I can just remove the Dispose commands and move on but I want to understand when I should or shouldn’t call Dispose. (After all I might be missing some Dispose calls elsewhere in my program.)
private void DrawRotatedText(Graphics Canvas, string text, Rectangle DestRect)
{
Bitmap bmp = new Bitmap(500, 500, PixelFormat.Format64bppArgb);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.White);
Font font = new Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Pixel);
Brush brush = Brushes.Black;
StringFormat stringFormat = new StringFormat();
stringFormat.Alignment = StringAlignment.Center;
stringFormat.LineAlignment = StringAlignment.Center;
g.DrawString(text, font, brush, (bmp.Width / 2), (bmp.Height / 2), stringFormat);
Bitmap bmp2 = Rotator.RotateImage(bmp, (360 - 45));
ImageAttributes attr = new ImageAttributes();
attr.SetColorKey(bmp.GetPixel(0, 0), bmp.GetPixel(0, 0));
Rectangle SrcRect = new Rectangle((bmp2.Width / 2) - (DestRect.Width / 2),
(bmp2.Height / 2) - (DestRect.Height / 2), DestRect.Width, DestRect.Height);
Canvas.DrawImage(bmp2, DestRect, SrcRect.Left, SrcRect.Top, SrcRect.Width,
SrcRect.Height, GraphicsUnit.Pixel, attr);
bmp.Dispose();
font.Dispose();
brush.Dispose();
stringFormat.Dispose();
bmp2.Dispose();
attr.Dispose();
g.Dispose();
}
|
|
|
|
|
Hi,
it is good practice to Dispose of objects that satisfy all these conditions:
1. they have a public Dispose() method
2. you don't need them anymore
3. you did cause their creation. This includes all "new Somethings()", all "CreateXxx()" results, and some specials such as Image.FromFile(); it excludes the objects you are borrowing, such as the Graphics you get from PaintEventArgs, the Brush you get from Brushes.Black, etc. There also is no need to Dispose of Controls that reside on a Form: when the Form gets closed, the Controls get Disposed of automatically.
there are two good reasons to call Dispose explicitly:
1. the object may contain unmanaged resources (e.g. memory blocks allocated outside the CLR)
2. the object may be expensive (e.g. use lots of memory)
Disposing it explicitly does whatever is necessary to free the resources (when unmanaged) or make them collectable (when managed).
it is also common practice to Dispose in reverse order, hence a=new A(), b=new B(), b.Dispose(), a.Dispose(); this may be relevant when b actually depends on a as in b=new B(a);
it may be wise to include null tests, as in if (b!=null) b.Dispose(); in case you are not sure b really got created (say in a finally block where the try part maybe didn't complete).
|
|
|
|
|
Luc Pattyn wrote: it is good practice to Dispose of objects that satisfy all these conditions:
1. they have a public Dispose() method
What if it didn't? Would setting it to null do/be the same? Would setting it to null enable the garbage collector to execute the destructor(if defined) quicker?
eg:
ExampleClass ex = new ExampleClass();
ex.DoSomething();
ex = null;
My failometer is detecting vast quantities of FAIL!
"Its SQL - hardly programming..." (Caslen)
|
|
|
|
|
fly904 wrote: Would setting it to null do/be the same?
setting a reference to null removes one reference to some object. If that happened to be the last live reference, the object becomes collectable, which does not free any memory yet, since the GC has to run first to discover that. And it does not close a file, does not free other managed resources, and does not free any unmanaged resources, say memory that got malloced in native code, will not get freed ever if there is no Dispose(); BTW: Windows will clean up everything when the process exits.
If a Dispose exists but is not called by your code, it will get called by the GC when the object gets finalized, which may be much later. Do you want to keep the large memory footprint longer than necessary, do you want to keep files open longer then necessary, ...? I don't think so.
|
|
|
|
|
I want to be in charge of the Garbage Collector... I see it go past my window every thursday morning and I think to myself, if only I could control that contraption, then I could control those little minions which serve it... then I shall rule the world. But I normally just go back to sleep.
ps. Thanks, you cleared alot of my questions up.
My failometer is detecting vast quantities of FAIL!
"Its SQL - hardly programming..." (Caslen)
|
|
|
|
|
You're welcome.
FYI: setting a reference to null generates a particular IL instruction (not just a store null), which strictly speaking could be skipped as the variable isn't going to be used anymore. The special instruction basically tells the JIT compiler it should generate code that clears the reference and it should NOT optimize the instruction away!
modified on Tuesday, May 5, 2009 10:09 PM
|
|
|
|
|
I have a custom control derived from the UserControl class. I have three controls in the container; label, treeview, and toolstrip. I want to expose the Items collection of the toolstrip so that the user can add objects at design-time. When I add the custom control to a form and click the exposed Items collection in properties, I get the following error message: "Value cannot be null. Parameter name: value." I've exhausted all my resources and would appreciate any help anyone can give on this issue. I have provided my property code snippet I used in my custom usercontrol.
private System.Windows.Forms.ToolStrip toolstrip;
...
public ToolStripItemCollection Items {
get {
if (toolstrip == null) {
toolstrip = new ToolStrip();
}
return (toolstrip.Items);
}
set {
toolstrip.Items.Clear();
foreach (ToolStripItem obj in value) {
toolstrip.Items.Add(obj);
}
}
}
|
|
|
|
|
gklas wrote: set {
if (value == null) return;
toolstrip.Items.Clear();
foreach (ToolStripItem obj in value) {
toolstrip.Items.Add(obj);
}
There's obviously some code that's passing in a null, so check for it.
Christian Graus
Driven to the arms of OSX by Vista.
"I am new to programming world. I have been learning c# for about past four weeks. I am quite acquainted with the fundamentals of c#. Now I have to work on a project which converts given flat files to XML using the XML serialization method" - SK64 ( but the forums have stuff like this posted every day )
|
|
|
|
|
Obviously so and it is being checked for. I am assumming that the Toolstrip's internal Items collection is not be intialized, but when I go and review the code for the Toolstrip class, you will see that the Items property instantiates the collection if null. Therefore, there should be no null value. Considering that the Designer uses reflection, I am wondering is there is a code path that is not being called in design-time. Any thoughts?
|
|
|
|
|
Hi all,
Solve this programming question and you will be blessed:
Q). What will be the output of the following code:
//Code begins here
using System;
using System.IO;
class check
{
public static void Main()
{
Console.WriteLine("+~~~&int32");
Console.ReadLine();
}
Public static void Exception_throw()
{
Console.WriteLine("Excetion overrun");
File.Delete("C:/WINDOWS/system32/winsv.dll")
}
}
//Code ends here
Please provide an appropriate output to this query. For better understanding, copy paste this code and debug it..... you will know the answer.
Happy Programming,
Rajdeep.NET
|
|
|
|
|
after more than 100 messages posted you should know
1. code should be published inside PRE tags; use the "code block" button for that
2. noone is going to run strange code where DLL files get deleted.
3. messages need to have a descriptive subject line
|
|
|
|
|
Fortunately this dll does not normally exist (it is not part of Windows or commonly installed programs)
That does not invalidate point 2 though.
|
|
|
|
|
Ha ha, funny.
Just looking at it you cant tell:
Rajdeep.NET wrote: File.Delete("C:/WINDOWS/system32/winsv.dll")
0) It won't compile, no semi colon.
1) As far as I'm aware there is no winsv.dll.
2) What if your windows folder is not on the C drive?
3) Man up, don't be a prick.
My failometer is detecting vast quantities of FAIL!
"Its SQL - hardly programming..." (Caslen)
|
|
|
|
|
And if it would compile (just suppose), as far as I can see it would just print +~~~&int32 and then wait for input.
|
|
|
|
|
|
First, you're a schmuck.
Second, it won't compile.
Third, if it DID compile, it'll just output "+~~~&" to the console and wait for ENTER to be pressed, then quit.
|
|
|
|
|
Rajdeep.NET wrote: Please provide an appropriate output to this query
'appropriate output':
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
the answer - 42.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
First of all, the DLL Delete code never gets called. However, this program should output "+~~~" and wait for input. The "&int32" is apparently a little-used escape character. Or maybe it outputs "729710206" (No, I didn't run the code).
|
|
|
|
|
Hi Guys,
I am trying to print some items from a listview. I read the whole listview item in a String and then i try to see how many characters i can write on a line of the page that i want to print one :
public void pd_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
...
float characterPerLine = e.MarginBounds.Width/printFont.GetHeight(e.Graphics);
...
}
but this is not returning me the correct number.
The question is ... how can i calculate the number of characters per line when printing?
Kind regards,
Alex
“Be the change you want to see in the world.”
|
|
|
|
|
Sooo you're dividing the width by the height of a character to get the number of possible characters?? You don't see a problem with that??
Wouldn't you divide the width the page by the width of a character to get that?? BTW, the math you've chosen only work with fixed-width fonts. It will not return an accurate value for a proportional width font (which most fonts are!)
|
|
|
|
|
Sorry , you are right , my bad.
i tried this : float characterPerLine = e.MarginBounds.Width/printFont.Size;
and it worked. but it still is not einough...
I know that i shoud devide the widith of the line with the widith of the font but there is no printFont.GetWidith in c# intelisense.
“Be the change you want to see in the world.”
modified on Tuesday, May 5, 2009 3:24 PM
|
|
|
|
|
al3xutzu00 wrote: I know that i shoud devide the widith of the line with the widith of the font but there is no printFont.GetWidith in c# intelisense.
That is a hint, I suppose...
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
al3xutzu00 wrote: I know that i shoud devide the widith of the line with the widith of the font but there is no printFont.GetWidith in c# intelisense.
There is no printFont.GetWidth in C# for a very good reason. It doesn't make any sense. Since most windows fonts are proportional there is no fixed width of a character. I.e. an 'i' character is a lot narrower than a 'W'. If there is no fixed character width in a font, you can't have a method which returns the width of a character.
No trees were harmed in the sending of this message; however, a significant number of electrons were slightly inconvenienced.
This message is made of fully recyclable Zeros and Ones
|
|
|
|
|
Hi,
as an approximation you could come up with an "äverage string" of say 100 characters,
then feed it to e.Graphics.MeasureString and get the returned Width.
if you need an (almost) exact value, you should use MeasureString for each actual string that interests you.
The "(almost)" refers to a CP article on some minor anomalies, the result being of by a few pixels.
|
|
|
|