|
It's possible that I didn't understand exactly what you meant, But what should I do with the inner references?
I'm not really sure as for the following, but AFAIK the GC will not collect an object which is still referenced somewhere.
Lets say both class A and B are referencing an object (and they both should NOT dispose of it). A and B are the only ones holding a reference to the object.
B should now be disposed of, but does not set the reference to the object to null.
Now A is disposing and sets the reference to the object to null.
Would the GC identify it needs to collect the object?
Or maybe it would decide not to collect it, because it is, seemingly of course, still referenced by the disposed/finalized B?
|
|
|
|
|
shyagam wrote: AFAIK the GC will not collect an object which is still referenced somewhere.
Correct. But, the issue is, you want to manage cleanup of some resources, right?
My point would be something like this
object C is the object that both A and B refer to.
object C contains a resource, which needs disposing of
object C keeps track of how many objects are referring to it
object A and B both refer to object C. So it has a reference count of 2.
object A calls Dispose and sets it's reference to null. object C internally does not dispose of the resource it holds, but it does drop it's counter to 1.
object B calls Dispose and sets it's reference to null. object C notices that it's reference count is now 0, so it calls Dispose on the resource in question
The GC cleans up the rest of object C, as nothing has references to it.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
shyagam wrote: AFAIK the GC will not collect an object which is still referenced somewhere
This is not correct. The "somewhere" in your statement must still be alive:
if the only references to Y are from inside objects that themselves are no longer
referenced, object Y is collectable (Otherwise two objects with cyclic references
would never die).
Furthermore, I would discourage the use of reference counts; it is cumbersome,
and when it goes wrong, your code becomes unsafe. It is better to create
a class Z (possibly a singleton) that holds your special resources, and has a Dispose
if applicable; when an object of class Z happens to be no longer referenced,
it becomes collectable (and its finalizer would call its Dispose in case you have
forgotten to call Dispose explicitly).
Remember: you should always call Dispose for objects that offer such method.
(On some classes it may have a different name, e.g. File.Close).
Luc Pattyn
|
|
|
|
|
Christian Graus wrote: You need a Dispose method if you want to offer a way to free memory immediately
Freeing (managed) memory is no reason to implement IDisposable.
The only time that there would be any point in having a Dispose method for removing references, is if you plan to hold on to the object after it's disposed. That sound's a bit creapy, though... like keeping your dead pets in the freezer...
---
single minded; short sighted; long gone;
|
|
|
|
|
Guffa wrote: Freeing (managed) memory is no reason to implement IDisposable.
Really ? Is the memory used by the Bitmap object unmanaged ? I'd say that if a large amount of memory is being used by commonly created objects, Dispose should be implimented to control cleanup. The framework does NOT manage it very well, I've seen a computer basically frozen, trying to solider on, because the GC had not cleaned up a bunch of objects.
Guffa wrote: The only time that there would be any point in having a Dispose method for removing references, is if you plan to hold on to the object after it's disposed
The point is, the Dispose method on the class in question, would be used to manage a resource count, before deciding if it should in fact call Dispose on an object which it contains.
Guffa wrote: That sound's a bit creapy, though... like keeping your dead pets in the freezer...
Have you not read Pet Cemetary ?
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Christian Graus wrote: I'd say that if a large amount of memory is being used by commonly created objects, Dispose should be implimented to control cleanup.
That makes no sense, as there is no way that you can free managed memory. You can remove the references to it, but it's still the garbage collector that frees it. once there is no reference to an object, it doesn't matter what references it contains. It makes no difference if the object references other objects or not, as the garbage collector doesn't consider references inside objects that no other object has a reference to.
Christian Graus wrote: The point is, the Dispose method on the class in question, would be used to manage a resource count, before deciding if it should in fact call Dispose on an object which it contains.
Each object should be owned by a single object that is responsible for it's life cycle. All other objects that use it should just leave it be and let it be disposed by the owner.
There might be situations where something similar to reference counting might be useful, but it's certainly not the first option. Also, I would definitely let the object itself keep track of the references, not the objects that uses it.
---
single minded; short sighted; long gone;
|
|
|
|
|
ARGGHHHH !!! I answered this at length, and CP crashed and my post was lost.
I am advocating reference counting because the OP said that multiple objcts need to track one resource. I am advocating a wrapper class, so the refrence count is internal to a wrapper class. I'm not typing the rest again, sorry, but the core was, you're right, managed memory can't be freed anyhow, I am just used to working with Bitmaps.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
If your object owns unmanaged resources (or objects that implement IDisposable), it should implement IDisposable. When you implement IDisposable, you should include a finalizer as backup.
Other than that, finalizers should rarely ever be used. It takes much longer for the garbage collector to free objects that has a finalizer. As they can't be freed right away, they will have to be moved to the next heap generation, which includes actually moving the entire object in memory.
Objects that doesn't own unmanages resources (or objects that implement IDisposable) don't need a Dispose method or a finalizer. You can just remove the reference to your object (or let it go out of scope), and the object will be freed by the garbage collector eventually.
If your object has a reference to an object that implements IDisposable, but is not responsible for it, you can just leave it be. You don't need to implement IDisposable to handle it, and you don't need to remove the reference. When there are no more reference to your object, the references inside your object doesn't count any more.
---
single minded; short sighted; long gone;
|
|
|
|
|
WoW.... It's an endless road of knowledge...
So many things to learn...
When I started developing in C#, I had a good understanding of C++ destructors, so I figured I knew all about them in C# as well (WRONGGGGG! ).
Anyhow...
Guffa wrote: Objects that doesn't own unmanages resources (or objects that implement IDisposable) don't need a Dispose method or a finalizer. You can just remove the reference to your object (or let it go out of scope), and the object will be freed by the garbage collector eventually.
If no finalizer is present, where than should I remove the reference to my object?
Also, is the last statement in the following code redundent?
I think of it as a good programming practice, as you can be sure that the reference was removed.
public void F()
{
Object obj = new Object();
obj = null;
} Should I simply let obj go out of scope to improve performance?
|
|
|
|
|
shyagam wrote: If no finalizer is present, where than should I remove the reference to my object?
If class A contains an object of class B that implements IDisposable, class A should also implement IDisposable, so it has a Dispose method where it can call Dispose of the object of class B.
If class A only contains objects that does not implement IDisposable, you don't need to remove the references to the objects.
Example:
Class A {
private List<string> _list;
public A() {
_list = new List<string>();
}
public List<string> List { get { return _list; } }
public Add(string s) {
_list.Add(s);
}
}
This is a class that contains a list of strings. As neither the List<> class nor the string class implements IDisposable, class A doesn't have to either. As class A only contains managed objects, you can just leave any objects of class A to the garbage collector, and it will efficiently collect the object, the list that it contains, and every string in the list.
Also, is the last statement in the following code redundent?
I think of it as a good programming practice, as you can be sure that the reference was removed.
public void F()
{
Object obj = new Object();
// Do some stuff with the object
obj = null;
}
You can safely remove the last line.
All local variables are allocated in the stack frame that is created when the method is called, and when the method returns, the stack frame goes away. The variables that were in the stack frame does not even exist any more, so setting the variable to null right before the method ends serves no purpose at all.
---
single minded; short sighted; long gone;
|
|
|
|
|
Hello, is it possible with C# to open up the user's default internet browser and take it to a certain web page? I would like it to open it outside the program (if you understand). If you can do this, is it possible to open any program?
|
|
|
|
|
Take a look at the Process.Start method.
To open a URL in the default browser simply type Process.Start("http://www.codeproject.com");
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
hi guys, The way i always connect to SQL through Visual studio is to use a dataset, sqlConnection and SQLDataAdaptor inorder to connect to my database, but imagin i take my Application to another computer and i want to install it there ! now i need to change the database location ! what is the proper way to do so, should i creat a class that keeps the location of my database so i can easily change it or is there any other way ???
Thanx alot guys ! You rock !
|
|
|
|
|
One way to do it is to use a settings file to store the path for the DB then set the ConnectionString accordingly.
private void Form_Load(object sender, System.EventArgs e)
{
string theFile;
string settingsFile = Application.UserAppDataPath + @"\settings.txt";
using (StreamReader reader = new StreamReader(settingsFile) )
theFile = reader.ReadLine();
this.oleDbConnection1.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source =" + theFile;
try
{
dataAdapter1.Fill(dataSet1, "table");
}
catch
{
MessageBox.Show("Database not found");
}
}
Hope this helps
Mike
Started out with nothing and still have most of it left!
|
|
|
|
|
Hi Mike, thanx man !
where is this setting text file stored ???
|
|
|
|
|
Your welcome
This is from the VS2002 help
=================
If a path does not exist, one is created in the following format:
Base Path\ CompanyName\ ProductName\ ProductVersion
A roaming user works on more than one computer in a network. The user profile for a roaming user is kept on a server on the network and is loaded onto a system when the user logs on.
==================
In my case its located in;
C:\Documents and Settings\Mike Hankey\Application Data\WoodWare\AreaEstimator\1.0.4.0\settings.txt
Glad to be of help. If you have any more questions would be glad to help.
Mike
Started out with nothing and still have most of it left!
|
|
|
|
|
You can put it in the config file for the application. It's an xml file, so you can easily edit it any time.
---
single minded; short sighted; long gone;
|
|
|
|
|
could you plz explain more ! how can i do that ?!
|
|
|
|
|
Search for "app.config read key"[^] and you will find a lot of information.
---
single minded; short sighted; long gone;
|
|
|
|
|
hi
i'm working with DataTables. my DataTable contains the record from a DB table in row and column format. i want to access the record value on a specific location in the datatable by specifying the row and column number, and then retrieving the value on that particular locaion.
how can i do it??
can u plz tell me the syntax
regards
Saira
|
|
|
|
|
Saira Tanwir wrote: my DataTable contains the record from a DB table in row and column format.
What do you mean by "row and column format"?
Saira Tanwir wrote: i want to access the record value on a specific location in the datatable by specifying the row and column number, and then retrieving the value on that particular locaion.
Sorry, I misread what you were saying - I thought you were asking about the table in the database...
In a DataTable you have a collection called Rows. You can access a row by its index
DataRow row = myTable.Rows[rowIndex];
You can then access the column by a column index.
object value = row[columnIndex];
You can't. Databases don't work like that. You can fake it if it is really what you need, but you'll need to add some sort of rownumber column to the table and it will be a real nightmare trying to keep it correctly updated.
A database works on "sets" of data. There is no built in order in a set. You can get the illusion of order by taking into account implementation details of specific databases. For example, in SQL Server you can create a clustered index (usually on the primary key) which will ensure that the data is physically inserted in the order of that index. You can use the ORDER BY clause to sort the rows as they are extracted from the database.
But at the end of it all there is no specific "get me row 42" functionality. SQL Server 2005 has some additional tools to help make faking this easier, but it is still an illusion.
-- modified at 13:11 Sunday 11th February, 2007
|
|
|
|
|
Hi, I am building a text editor, and I would like to undo the last thing done.
so, I used the Undo() method, but found it undoes everything changed, how can I set it so it only changes the LAST thing done?
My code was:
<br />
<br />
rchTextCode.Undo();<br />
<br />
|
|
|
|
|
Err..i haven't realy tested it but how about....rchTextCode.Text.Undo()?
of cource it'll delete everything if u tell it to undo the entire textbox and not the text it in...
|
|
|
|
|
sharpiesharpie wrote: Err..i haven't realy tested it but how about....rchTextCode.Text.Undo()?
This won't work as the String class defines no Undo method.
sharpiesharpie wrote: of cource it'll delete everything if u tell it to undo the entire textbox and not the text it in...
The Undo method only operates on the text of the text box (see the documentation). He meant that it undos all changes applied to the text and not all changes applied to the text box itself.
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
Actually, there is a rtf.Text.Undo method...
|
|
|
|
|