|
Presumably you know this because you have gotten a CompletedSynchronously and you have gotten a InvalidOperation after that?
If so then there are two possibilities.
1. There is no data.
2. It is in the IAsyncResult somewhere.
|
|
|
|
|
1. Not true
2. Nowhere to be found.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
You are claiming that there is data even though you can't find it.
I suspect that you assume there is data - which is not the same thing.
|
|
|
|
|
Hey. Sorry if i have not quite got the lingo but here goes.
So i have declared an instance ('finalCellCompiler') of the CompileFinalCell class globally (for access across the whole form) and upon clicking the twoDDisplay button on the form finalCellCompiler is initialised with the *new keyword.
The CompileFinalCell class features the IDisposable wrapper and a dispose method to dispose of the object. A seperate reset button calls the clear method to get rid of the finalCellCompiler object.
The issue i have is that after calling the reset method and subsequently the twoDDisplay i get two instances of the finalCellCompiler as when i click a third button 'depositNext' (which is handled inside the CompileFinalCell class) the messageBox is call twice from each instance.
I am trying to figure out a way of replacing the original instance without creating major modifications to my code.
Any help would be greatly appreciated. Thanks.
public partial class Form1 : Form
{
private CompileFinalCell finalCellCompiler;
private void twoDDisplay_Click(object sender, EventArgs e)
{
finalCellCompiler = new CompileFinalCell(this,
fibrePositionGenerator, unitCellData.outerCellSize,
finalBeamForce, finalShellForce);
}
private void Clear()
{
if (finalCellCompiler != null)
{
finalCellCompiler.Dispose();
finalCellCompiler = null;
}
GC.Collect();
}
}
class CompileFinalCell : IDisposable
{
Form1 _form1Data;
public CompileFinalCell(Form1 originalFormData,
FibrePositionGenerator fibreData, SizeF outerCell,
ForceDirectedAlgorithm beamForce,
ForceDirectedAlgorithm shellForce)
{
_form1Data = originalFormData;
_form1Data.depositNext.Click += new
EventHandler(depositNext_Click);
}
private void depositNext_Click(object sender, EventArgs e)
{ MessageBox.Show("Button clicked"); }
public void Dispose()
{ GC.SuppressFinalize(this); }
}
|
|
|
|
|
The easiest way to achieve this would be to have a null check in your twoDDisplay_Click method to identify whether or not finalCellCompiler has previously been instantiated. If it has, don't do anything. BTW - it's generally not a good idea to force the garbage collector; let the runtime take care of that for you.
|
|
|
|
|
Hi, i know its not good practice to use the GC but i have been going round in circles trying to find a solution. I have checked finalCellCompiler when executing the twoDDisplay_click and it is equal to null before the new instance is created but i still appear to have two instances. And the more and more times i execute the reset button and then the twoDDisplay method i end up with more instances. I must be doing something fundamental wrong...?
|
|
|
|
|
Hi,
your CompileFinalCell objects never die; you may throw away the reference to them by setting finalCellCompiler = null; , however they are still reachable as they have attached themselves to your Form1 by executing
_form1Data.depositNext.Click += new EventHandler(depositNext_Click);
so as long as the Form is alive, so will all CompileFinalCell instances.
One way to resolve this is by having a counteraction inside the Dispose() method. Use -= as you did += .
I have some comments on your approach:
1.
it isn't quite all right to have an object modify its surroundings, as in _form1Data.depositNext.Click += new EventHandler(depositNext_Click); . One normally has the outer object to manage the inner ones, not the other way around. A room would know how many chairs are inside, the chairs wouldn't know about the room they are in. It is fundamentally wrong to pass Form1 into the CompileFinalCell class, your CompileFinalCell objects have a life of their own with or without some form. The right way would be to have events defined in CompileFinalCell, and the external world (the Form) to subscribe to those events, using delegates.
2.
From the code shown, I'm not convinced you need or want IDisposable, Dispose, and SuppressFinalize. But then, maybe you simplified the snippet.
3.
You trying to control the garbage collection is bad, as you know. When running in circles, keeping the things you know are bad is a sure way of not leaving said circles.
|
|
|
|
|
You are indeed correct, it was the event handler that was causing the problem. Thanks very much for this.
I am still learning so yeah there are some fundamental rules i am breaking. The reason for creating the event handlers inside the classes instead of the form1 was to keep things manageable (for me) as the application is quite large and there is a lot already going on in form1. I didn't see it to be too much of an issues but then again my program has a habit of crashing every no and then. I know its bad practice and when i get chance i will change it.
I dont think i actually need the dispose method for this particular class but for others it significantly reduced the amount of RAM i was using when using the profiler.
Is it bad to call the GC.Collect() method when performing intensive tasks or is that ok?
Thanks for the advice, it is much appreciated.
|
|
|
|
|
R4jlu wrote: Is it bad to call the GC.Collect() method
Yes, it is. The GC will collect when it needs more memory than is currently available (i.e. when you create another probably big object); there typically is no reason to free memory earlier than that (your app's memory most often isn't going to return to Windows anyway). So let it perform its job the way it thinks best.
You may start using GC judiciously after you have become an expert programmer...
|
|
|
|
|
The only times I have ever found that I've needed to call GC.Collect is when my underlying code was wrong. In every case, when I've tried it and gone back later, I've identified why my naff code needed to be changed - and the collection removed.
|
|
|
|
|
On Windows, I hardly ever instruct the GC to do things for me, there isn't much point in it. On embedded systems, I tend to tell the GC (not the Windows one!) to have a feast while the system is in a calm state, i.e. in between two real-time sessions; that means spending cycles in advance, before the next rush.
modified 3-Oct-11 11:35am.
|
|
|
|
|
The only time I can see that it makes sense is if you've just finished an intensive job, de-referenced a huge data block and know that you (probably, at least) have a bit of downtime before some more intense work that will create more huge data (and therefore definitely trigger the GC at a worse time). For example, something like a simulation web service, or embedded stuff as Luc mentions (where the definition of 'huge' is a lot smaller and you have to care about memory). One might argue that one shouldn't be writing such things in a managed environment anyway, but if you find yourself having to do so then nudging the GC might make sense.
But yes, in terms of answering a newbie question, you should never call GC.Collect.
|
|
|
|
|
Cheers guys.
I am in the process of removing any sections where i have interfered with the GC. There are a couple of operations that seem to make a significant difference to the RAM so i will leave them for the time being until i get round to resolving them.
I take it, its safe to use the dispose methods of third party wrappers i.e. DirectX meshes and so forth?
Thanks again
|
|
|
|
|
R4jlu wrote: I take it, its safe to use the dispose methods of third party wrappers i.e.
DirectX meshes and so forth?
Safe - and probably necessary. If they've provided them, they've provided them for a reason.
|
|
|
|
|
As has been hinted at above, you've got the dependency backwards with that event handler. If a CompileFinalCell is a temporary thing owned by the form, if possible the calls should all go from form to compiler:
public partial class Form1 : Form
{
private CompileFinalCell finalCellCompiler;
private void twoDDisplay_Click(object sender, EventArgs e)
{
finalCellCompiler = new CompileFinalCell(this,
fibrePositionGenerator, unitCellData.outerCellSize,
finalBeamForce, finalShellForce);
}
private void DepositNextHandler(object sender, EventArgs e) {
if(finalCellCompiler != null) finalCellCompiler.DepositNext();
}
private void Clear()
{
if (finalCellCompiler != null)
{
finalCellCompiler = null;
}
}
}
class CompileFinalCell
{
public CompileFinalCell(FibrePositionGenerator fibreData, SizeF outerCell,
ForceDirectedAlgorithm beamForce,
ForceDirectedAlgorithm shellForce)
{
}
public void DepositNext()
{ MessageBox.Show("Button clicked"); }
}
You don't need to implement IDisposable on something which has only managed references, as a general rule (it's designed for releasing system level things like file handles, graphics objects, fonts etc which are limited in number and it's important that you clean up quickly).
Edit: oh yes, don't forget to hook up that button click handler in the form's designer.
This also has the (major) benefit that the final cell compiler is now independent of the UI, i.e. you could create it in a background thread, from network input, as a scheduled service etc without having to change the code.
If the compiler needs to communicate back the other way, you should give it events which the form can then hook onto.
|
|
|
|
|
Hi there,
I am working on a project in C#. I have a problem rearranging my controls on form when I click the maximize button of my form. I mean whatever the positions I have placed my controls on form, they remain on the same position even if I am going to maximize the form. I want to solve this problem so that whenever I maximize my form the controls should rearrange appropriately. Any help in this regard will be hightly appreciated. Thanks.
|
|
|
|
|
Use the Dock[^] and Anchor[^] properties of the child controls.
This[^] article may also be helpful.
|
|
|
|
|
Thanks Shameel for your help. I have already tried Anchor and Dock properties of the individual controls but they are not solving my problem. What I really need to know is that whenever I resize the form during run time, all my controls should be on the same locations with an increase or decrease of their propotional widths and heights, so the look and feel of the form should not be affected. Is there any way to do that? Thanks.
|
|
|
|
|
You generally don't want to do that, as a lot of controls (basically anything which includes text) aren't designed to be resized in such a fashion.
|
|
|
|
|
How do you get an Idle Message in a UserControl class in C# / Silverlight?
|
|
|
|
|
hi everyone
i need to get the Url of a frame from IE or another browser but i don't know how xD
in this moment, i can find url in the address bar using DDE service DDe to get url from browsers
so please if any one have an answer about getting the frame's url it would be so nice
thanks
|
|
|
|
|
I want a code for retrieving HDD serial number in C#,can you please help me?
|
|
|
|
|
|
There is no single method for getting a hard drive serial number. WMI does not work in all cases because the is no mandate that says every manufacturer has to support it.
There are about 4 different methods for getting a hard drive serial number. None of them work on all hard drives. It's best to use multiple methods to be sure your actually getting the correct information.
There are libraries out there that will do this for you, such as this one[^]. I haven't used it though, nor any other library for this.
|
|
|
|
|
Adding to what others have said, on Vista and later you may get UAC trouble, as getting physical information is considered dangerous. Having some kind of solution that works on XP is no guarantee it will work on more recent Windows versions.
|
|
|
|