|
Ok, thanks.
However, this is not without pain. It seems like by saying:
using(someobj = new someclass()) {}
the Dispose method will be called, while doing:
someobj = null;
will NOT trigger the Dispose method. Does this mean that if I want to manually force the memory management to deal with it I have to say:
someobj.Dispose();
someobj = null;
In that case, just making a Close method where I close all resources manually seems a lot easier in the short run, since the whole point of my post was to avoid such manual labor in an attempt to release all resources automatically.
Although the GC will "eventually" trigger the destructor when just kicking the objekt out of scope, this seems a bit weird since I have not been able to release files in the destructor without exceptions saying there are none.
|
|
|
|
|
In .net Framework if you set someObj to null GC will trigger automatically after a period of time and will free up the memory of all the objects which are no more referenced. You write the Dispose method for clearing up the un-managed resources. for example you have a connection to database and you want to close it etc.
Ahsan Ullah
Senior Software Engineer
|
|
|
|
|
Does this mean that:
1) I must explicit call Close() on file handler after I am done just to be certain they are closed instead of waiting for the GC to run the destructor? Although I failed at closing the file handler in the destructor as well since the file handler object (StreamWriter) was already disposed at this point.
2) the Dispose method is only called when wrapping the allocation in the using() {} block, and not when the GC comes to clean it up?
3) Any object created without storing the address will eventually be removed despite being "in use"? E.g.
I have sometimes used an object where the constructor starts a new thread with code execution, and created the new object by just saying
new HandlerObject();
as a statement, without storing the returning reference.
Sorry for the trouble, I just really want to understand this.
|
|
|
|
|
Check out this article[^] for some more detailed explanations of how to implement the Dispose pattern.
You have several questions through this thread, so I'll try to address each of them here:
Since the .NET runtime is a garbage collected system, the rules of memory allocation/deallocation you were familiar with from C++ do not completely apply. Specifically, the runtime is not deterministic, so you have (effectively) no control over when an object actually gets removed/deallocated from memory.
The purpose of the Dispose pattern and the IDisposable interface is to provide a more deterministic means to allow your object to clean up both managed and unmanaged resources. This should apply if you directly contain unmanaged resources or any objects you contain or derive from implement IDisposable . The other thing to keep in mind is that the .NET runtime knows how to clean up managed code, but if you make use of any unmanaged (native) resources it will not know how to clean up those resources...that's the purpose of the Dispose method.
In .NET there really isn't a destructor, at least not in the same way that C++ provides a destructor. Unfortunately, Microsoft chose to use the same syntax for a C++ destructor to implement a C# Finalizer. These are by no means equivalent and there are very few cases where you would actually need to write a finalizer. Finalizers are difficult to write correctly and add overhead to your object, so they are best avoided when possible.
The using statement:
using (DisposableObject d = new DisposableObject())
{
} will effectively be translated by the compiler to:
DisposableObject d = new DisposableObject();
try
{
}
finally
{
((IDisposable)DisposableObject).Dispose();
} Generally, setting an object explicitly to null has no real effect on the GC. (There are exceptions to this, but they are for large objects, over 64K in memory size.) This isn't to say that this is the only time the Dispose method (or your finalizer if you write one) will be called. When the GC runs a collection cycle, it will try to determine if it needs to call Dispose on the object being collected...if so, it will go ahead and run it. The problem here is that, at this point, you have no control over when Dispose gets called.
As far as implementing a Close method, there is nothing wrong with doing so within the guidelines of the Dispose pattern if that makes more sense semantically for your object. In that case, the Close method should actually do the work and the Dispose method should simply call Close .
Even though the Dispose pattern is about memory management and object lifetime management, just because an object goes out of scope does not mean that it will be collected. The GC runs when it determines a need to run, so an object may actually "live" for a while after it goes out of scope. Calling Dispose when that object goes out of scope, however, tells the runtime that you are done using the object and that it should cleanup any resources it maintains. This is different than being collected by the GC.
If your object maintains any unmanaged resources directly, maintains any managed resources that implement IDisposable , or any class in your inheritance chain implements IDisposable you should also implement IDisposable and in your own Dispose method clean up the unmanaged resources and call the Dispose() method on each of your managed resources and/or your base class.
Finally, your question of "Any object created without storing the address" isn't completely clear to me. In your example, how would you ever use the instance of HandlerObject() you created without storing a reference to it? In this scenario, I believe the only time this object would get disposed is when the GC runs a collection cycle and it is no longer in use; since there is no accessible instance of the object, you have no way to call Dispose() explicitly.
Scott Dorman Microsoft® MVP - Visual C# | MCPD
President - Tampa Bay IASA
[ Blog][ Articles][ Forum Guidelines] Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
|
|
|
|
|
Thanks for the excellent information. So to sum it up, when will the Dispose() method be called? at the end of using() {} and whenever I call it explicitly, and when the GC decides that "for this object the Dispose() method needs to be called" ? Or will it happen for every object that has the IDisposable interface implemented?
By the way, is a filehandler even needed to be cleaned up in the Dispose() or will the StreamWriter Disposer take care of it automatically?
What I mean with the latest is as follows: I wrote a small tcp server app once. In this app I had a main thread that just waited for connections. When the connection was established, a new object was created and left "on its own" for processing. I will try to illustrate by some pseudo-code:
class Handler
{
private Socket sock = null;
private Thread t = null;
public Handler(Socket new_socket)
{
sock = new_socket;
t = new Thread(DoSomeStuff());
}
public void DoSomeStuff()
{
}
}
server.Listen(10);
while(true)
{
Socket new_client = server.Accept();
new Handler(new_client);
}
As you can see, each handler live on its own and no reference is needed in the main thread after the object is created since the object/thread will do ALL the processing on the established connection. Will the Handler() object in this case be marked as "to be collected by the GC" since I don't have any references to the object? Is this just plain BAD code to solve the problem in terms of memory management?
|
|
|
|
|
invictus3 wrote: Thanks for the excellent information.
You're welcome.
invictus3 wrote: So to sum it up, when will the Dispose() method be called? at the end of using() {} and whenever I call it explicitly, and when the GC decides that "for this object the Dispose() method needs to be called" ? Or will it happen for every object that has the IDisposable interface implemented?
The Dispose method will be called:- At the end of the using statement.
- When you call it explicitly.
- When the GC runs a collection cycle and decides that an object needs to have the
Dispose method called. If an object implements a Dispose method without implement the IDisposable interface, there is no guarantee that the GC will actually call the Dispose method. (I'm reasonably sure that it will, but not positive and it shouldn't be an action that is relied upon. If you need to clean up resources for your object, you should always implement IDisiposable .)
invictus3 wrote: By the way, is a filehandler even needed to be cleaned up in the Dispose() or will the StreamWriter Disposer take care of it automatically?
I think this depends on how you are using the objects. If you're talking about a file handle that is created inside the StreamWriter , then calling Dispose() on the StreamWriter will take care of disposing the file handle.
Ok...seeing your psuedo-code makes the question clearer. In that scenario, your Handler class should have implemented IDisposable in order to tell the sockets to clean up after themselves. Since you don't maintain a reference to the created Handler objects, the rules actually get a bit muddier. Most likely, the objects will get collected when the application ends as it may be difficult for the GC to determine if the Handler object is being used. Depending on how your DoSomeStuff() method was actually coded, you could possibly insert a call to GC.KeepAlive() to prevent the object from being collected too early.
I probably would have implemented this so the server object maintains a collection of handler objects, which would allow you to have a bit more control over when the handlers are disposed of.
Scott Dorman Microsoft® MVP - Visual C# | MCPD
President - Tampa Bay IASA
[ Blog][ Articles][ Forum Guidelines] Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
|
|
|
|
|
One more question related to this. When I use a TcpClient, I will also create a NetworkStream (for creating readers/writers, and for closing the connection), a StreamReader (for reading data) and a StreamWriter (for writing data).
Everyone of these have a Close method. The TcpClient one only disposes the object, while the other three both closes the connection AND disposes the object.
Assuming that I Close() (and by this also dispose) the NetworkStream, do I really need to do this on the other 3 objects? I.e. once the underlying connection is closed using the NetworkStream.Close(), do I really need to dispose the other objects explicitly, or is it sufficient to just wait around for the GC to clean up the mess?
I am aware that this may look like a network programming question, but from I wonder mostly on the memory management part of this question.
|
|
|
|
|
I am trying to us Google Contact API to read in the Address Book in Google. I am able to get the verification screen and the token (after selecting 'Grant Access'). However, the following line
AuthSubUtil.exchangeForSessionToken(strSessionToken, null) always throws exception like
Execution of exchangeForSessionToken and the inner exception is
The remote server returned an error: (403) Forbidden.
I have also followed the discussion thread here
http://groups.google.com/group/Google-Accounts-API/browse_thread/thread/8c9a023e990566ee/5a85bbcf8b084c18?lnk=gst&q=Execution+of+exchangeForSessionToken#5a85bbcf8b084c18.
Since I am using unregistered mode and okay with the validation prompt
by Google, I am passing null as the second parameter. Also, I have verified the headers in every request with Fiddler Tool and they are identical.
Any help?
Vasudevan Deepak Kumar
Personal Homepage Tech Gossips
All the world's a stage,
And all the men and women merely players.
They have their exits and their entrances;
And one man in his time plays many parts... --William Shakespeare
|
|
|
|
|
I guess this is more a virtual machine question.
We struggling with a project that reads a lot of tiny xml files mostly static files to build a action table.
Each user can get multiple instances of control interface that uses these action tables. The first obvious enhancement is to build the tables on a back ground thread; though by using a static object the files only have to be read once and shared among the control instances.
My question is if there are multiple users on a terminal server machine do they share the same static object?
Thanks
|
|
|
|
|
fredsparkle wrote: I guess this is more a virtual machine question.
What are you doing in C# thn?
Please remember to rate helpful or unhelpful answers, it lets us and people reading the forums know if our answers are any good.
|
|
|
|
|
Syntax assitance and command history for various command line driven remote interfaces from various vendors.
|
|
|
|
|
fredsparkle wrote: My question is if there are multiple users on a terminal server machine do they share the same static object?
No. Each application instance has its own instance of a static object.
|
|
|
|
|
Hello,
I have some file processing in an application. When I'm done - I need to move the files.
But I am getting "Access denied. the file is being used by another process" error. Here're some of my code:
<br />
DirectoryInfo di = new DirectoryInfo(path);<br />
<br />
FileInfo[] files = di.GetFiles(searchPattern, SearchOption.TopDirectoryOnly);<br />
foreach (FileInfo file in files)<br />
{ <br />
if(valid){....processing<br />
try{<br />
file.MoveTo(...);<br />
}<br />
..<br />
}<br />
else{<br />
try{<br />
file.MoveTo(...);<br />
}<br />
}<br />
}<br />
Any idea whats wrong?
Thanks.
|
|
|
|
|
Did you already close the Stream?
Please remember to rate helpful or unhelpful answers, it lets us and people reading the forums know if our answers are any good.
|
|
|
|
|
You need to close the files after processing and before moving.
|
|
|
|
|
Thanks to both of you Manas and Centriste.
I was not using file.Open(), so I didn't use Close either.
But, I am using a reader and I needed to close that.
Eh.
Thanks again.
|
|
|
|
|
I would to populate a country combo box using a collection. The code for the collection is below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BUI
{
public class CountryCollection : BUIBaseCollection<Country>
{
public static CountryCollection FetchList()
{
CountryCollection obj = new CountryCollection();
obj.MapObjects(new DAL.Country().FetchList());
return obj;
}
}
}
Fetchlist is a stored procedure that returns all records in a table. My problem is to populate my combo box I am using this code:
this.cmbCountry.ItemsSource = BUI.CountryCollection.FetchList();
and instead of displaying the items in the table, it is displaying:
BUI.Country
BUI.Country
BUI.Country
Thanks
Jonso
|
|
|
|
|
Combobox shows data returned by calling ToString() on class BUI.Country It seams that you haven't overridden ToString() method in your class so class name is returned. Override ToString() in BUI.Country class to return the data you want.
Giorgi Dalakishvili
#region signature
my articles
#endregion
|
|
|
|
|
Another way, you can use the following to specify which column you want to bind.
this.cmbCountry.DisplayMember = "FieldName";
this.cmbCountry.DataSource = BUI.CountryCollection.FetchList();
Where "FieldName" above is the name of the field which stores the list of countries.
Sunny Chen
===============================================
System Analyst, System Architect
Consultant of China System Analyst Institution
http://www.sunnychen.org
===============================================
|
|
|
|
|
Hi
I have a query with the ListBox control. I have two pages on my web app, a main page and a sort page.
The main page contains a table populated with names from a SQL database.
The sort page contains a ListBox with all the names from the main page and 2 buttons, Up and Down.
The user can move the names Up and Down by clicking the name and pressing Up or Down.
Now i would like to know, How can i save the 'sorted' listBox and display that order on the Main Page??
I would greatly appreciate some help.
Many Thanks
PS this is what i have for moving the items UP/Down
protected void Button1_Click(object sender, EventArgs e)
{
int i = lstBox1.SelectedIndex;
string str = lstBox1.SelectedItem.ToString();
if (i > 0)
{
lstBox1.Items.RemoveAt(i);
lstBox1.Items.Insert(i - 1, str);
lstBox1.SelectedIndex = i - 1;
}
}
-------------------
Redcastle CRM
|
|
|
|
|
Sorry forgot to mention, I need to have these 2 pages. Everything one 1 page is not suitable in my case.
Many Thanks
|
|
|
|
|
What you need to do is save this information(of ordering done at Sort Page) in your database.
Please remember to rate helpful or unhelpful answers, it lets us and people reading the forums know if our answers are any good.
|
|
|
|
|
FYI...
Blog link to be reinstated at a later date.
|
|
|
|
|
Hi,
I have a Windows database application that uses MS Access for the database. I decided to embed the database into the application and now can't connect to the mdf file. The connection string I used before I embedded it is:
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + APath.Replace("bin\\Release", "") + "\\Database\\Bix.mdb;Jet OLEDB:Database Password=Password;
(APath is Program.AppPath)
Can anybody tell me how I should modify the connection string so that I can connect? I presume that it would be the "Data Source" portion. I've tried looking up the syntax but haven't found anything that works.
Thanks in advance for the assistance.
|
|
|
|
|
Member 2265148 wrote: Windows database application
Member 2265148 wrote: I decided to embed the database into the application
How did you embed that?
Member 2265148 wrote: APath.Replace("bin\\Release", "")
Why this?
Please remember to rate helpful or unhelpful answers, it lets us and people reading the forums know if our answers are any good.
|
|
|
|