|
I'm not sure what you mean. I'm creating TreeView derived control programmatically and I'm not able to disable "Close" button.
|
|
|
|
|
In .Net a TreeView is a control. Controls go on forms. FOrms are then displayed to the user. The close button is on the form. To disable the close button you must access the properties on the form.
If your not putting your treeview on a form what are you doing?
Edit:
Are you talking about WinForms or Asp.Net?
|
|
|
|
|
Do you mean "collapse"? To keep the nodes from being collapsed? (Not closed?)
|
|
|
|
|
Does anyone know of an alternative to Pegasus' ImagXpress for opening/viewing/scrolling an image? The product works very well, but the licensing fees are way too high ($60,000-$100,000).
Thanks
R.Myers
|
|
|
|
|
Leadtools - www.leadtools.com/
or
Accusoft - www.accusoft.com/
Leadtools has no runtime fees, which is pretty darn nice. Pegasus looks like a great product, but how in the heck do they justify the pricing structure?
|
|
|
|
|
Thanks, I appreciate the input.
|
|
|
|
|
Most of the Image toolkits are expensive and have some form of runtime licenses or reporting requirements. I have used Accusoft controls in the past, from a development perspective it is easy to use and feature rich. Unfortunately, they have a runtime license fee as well as quarterly reporting requirements (At least last year).
|
|
|
|
|
Do you happen to know what the pricing was on that? Just a ballpark figure.
Thanks
|
|
|
|
|
The Accusoft website. The pricing is, from what I remember, was around $1400 per developer and $8 per user for runtime royalities, plus annual maintenance.
|
|
|
|
|
Help me to get the memory details as u retrieve the hardware info.
If possible send the code
|
|
|
|
|
You can retirve hardware configuration information via WMI[^].
Here's some info on how to access it from C#:
C# WMI[^].
|
|
|
|
|
What is the use of having Dispose() method in class. All .NET classes are under managed code and garbage collection will be done automatically. But some classes like Dataset having dispose method. When we need to use dispose method for our class ? Writing dispose method for all classes is a good practice ?
|
|
|
|
|
Hello,
I often implement "IDisposable" with the Dispose method to unregister delegates to manager classes (classes which are allways in memory in my app) there.
All the best,
Martin
|
|
|
|
|
Thanks you. So if the code is 100% managed, do we need to implement this ?
|
|
|
|
|
|
AS A USER...
You should call Dispose() if that is the only way to clean up, as is typically the
case when unmanaged resources are involved.
You should call Dispose() if the class offers that method, since you don't know
whether it is using unmanaged resources; example OpenFileDialog()
For Framework classes you should read MSDN, and pay attention to the remarks it
contains regarding Dispose(), Close() and the like.
BTW: In C# the best way to call Dispose() often is with a using construct.
AS A PROVIDER...
You should do the reciprocal, including:
You should implement IDisposable if your object is likely to hold large amounts of
(managed) memory that you want to make collectable immediately, or some resources
you want to free immediately (e.g. an open file).
If your class has a Dispose() you should clarify its use in your documentation.
|
|
|
|
|
Luc Pattyn wrote: You should implement IDisposable if your object is likely to hold large amounts of
(managed) memory that you want to make collectable immediately
Actually, there is rarely any reason to try to release memory earlier. You might even end up holding on to the memory longer than if you didn't try to release it.
Example:
ObjectWithHugeArray obj = new ObjectWithHugeArray();
obj.GetSomeData();
obj.DisplayTheData();
GetSomeUserInput();
obj.Dispose();
obj = null;
ObjectWithHugeArray obj = new ObjectWithHugeArray();
obj.GetSomeData();
obj.DisplayTheData();
GetSomeUserInput();
obj = null;
(Yes, the example is a bit silly, but it tries to show that sometimes the garbage collector is smarter than the programmer...)
---
single minded; short sighted; long gone;
|
|
|
|
|
Hi Guffa,
Guffa wrote: ObjectWithHugeArray obj = new ObjectWithHugeArray();
obj.GetSomeData();obj.DisplayTheData();
// the memory is collectable here already
GetSomeUserInput();
obj = null;
I think I don't agree in general and with the // comment in particular.
I assume you intend the example to be the code of a single method, with obj
a class member, not a local variable.
(if it were a local variable, setting it to null with no statements following
that use it's value, the "obj=null;" statement would be chopped out
by the optimizer).
Not having an obj.Dispose(); ends the life of the obj value sooner when
looking at the code in the method itself; IMO that on its own is insufficient to
expect the compiler to move "obj=null;" upwards. And it is not allowed to move
it over the GetSomeUserInput() method call, without making sure the value of obj
isnt used in there.
So I expect the obj variable be present on the stack, and be cleared only
after returning from the Input method; hence the GC would find the hugeobject
reference, and would have to keep it alive (together with its huge array, for
which my Dispose() would have removed the only reference).
So I don't see how your example works in substatntiating your statement
that Dispose() could work adversely, which I still don't see possible.
|
|
|
|
|
Hello Luc,
Luc Pattyn wrote: with obj
a class member, not a local variable.
But the example looks like it is a local vatiable, doesn't it?
"ObjectWithHugeArray obj = new ObjectWithHugeArray();"
Luc Pattyn wrote: the "obj=null;" statement would be chopped out
by the optimizer
Really!
I use it very often, because I thought it is recomended behaviour, to help the GC.
I think there was a discussion in the past about that, let me look!
-- modified at 11:28 Monday 30th July, 2007
Found it, Scott Dorman gave me that information[^] some time ago.
All the best,
Martin
|
|
|
|
|
Hi Martin,
it will require more investigation; seems the C#2005 compiler is dumber than
I expected (I don't know what the JIT does to it).
Even in release mode, it keeps both "ref=null;" and "val=12;" statements,
even as the last line of a method and for local vars.
For value types that does not make sense at all.
For ref types it could make sense (to throw away the reference, so the object
may become collectable); here the compiler may be keeping it on purpose in
general, but keeping it for a local ref on the last line does not make any sense.
Whatever the compiler does to it, it makes sense (and I apply it too) to
nullify a ref that is a class member everywhere in your code, and I guess
they have (and should have) done something special so you could nullify a local ref
anywhere in a method to throw the ref away earlier than method exit.
I will tell when and if I have more on this.
|
|
|
|
|
Hi Martin,
I investigated the GC stuff somewhat deeper, see here[^]
Net result is: ptr=null; makes sense, the compiler uses a "ldnull stloc" instruction sequence, which the JIT will not move or optimize away.
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
Hello Luc,
Very interesting!!! (Got my five)
Thank you for taking time!
I followed this thread every day (have it in my Favorites), because it was interesting for me.
I was a little surpriesed that the disussion between you and Guffa ran in a "wrong" (abuse) direction.
Hope it doesn't change your behavioure her on CP.
Go on with the good work!!!
Thanks again!
All the best,
Martin
|
|
|
|
|
Luc Pattyn wrote: I assume you intend the example to be the code of a single method, with obj
a class member, not a local variable.
Assume away.
It's a local variable.
Luc Pattyn wrote: Not having an obj.Dispose(); ends the life of the obj value sooner when
looking at the code in the method itself; IMO that on its own is insufficient to
expect the compiler to move "obj=null;" upwards.
The compiler will not move the "obj=null;", and it doesn't have to. That statement is irrelevant for the live time of the reference to the object, as it doesn't use the reference, it only assigns a new value to the reference variable. The last use of the reference is where it's read, not where it's written.
Luc Pattyn wrote: So I expect the obj variable be present on the stack, and be cleared only
after returning from the Input method; hence the GC would find the hugeobject
reference, and would have to keep it alive (together with its huge array, for
which my Dispose() would have removed the only reference).
No, the object only have to be alive as long as there is a used reference to it. The garbage collector sees where the reference to the object is last used, and can collect the object before the input method. If you have a Dispose call, the object has to be kept alive until then.
---
single minded; short sighted; long gone;
|
|
|
|
|
Hi Guffa,
you're not convincing me at all.
Guffa wrote: the object only have to be alive as long as there is a used reference to it. The garbage collector sees where the reference to the object is last used
You assign magic powers to the GC; it does not understand your program, it can't
predict whether an existing reference is still needed or not.
This is a first approximation on how a GC basically works: the only thing the GC
sees is a process with a bunch of threads; each thread has a stack and its copy
of the CPU's registers. When the GC wants to get an updated view on things,
it suspends all threads in the process, then deals with each thread in turn.
Inside each stack and register set, it scans for references, to build one big
list of things it can see; afterwards it loops over all existing objects (they
all are in a linked list), and removes the ones that don't appear in the
list of reachable objects.
The local ref-type variable is located on the stack (or JIT-optimized into a
register). If it is not null, the object it refers to is alive, even if the
program does not intend to use it any more. That's exactly why it may be wise
to assign null to it.
Now my problem was: why would the compiler actually generate code to assign
null to it, since there is no further use for it; a regular non-CLR compiler
(say a C compiler) would optimize it away immediately. But it seems the C# compiler
designer has not optimized assignments that far that "obj=null;" would be
removed. (Unfortunately he also did not remove useless val-type assignments,
try ending a method on int a=12; and watch its MSIL).
So I still believe "obj=null;" is useful if obj is not a local variable,
as well as for a local variable that half-way the method is no longer needed.
If you don't assign null to the local variable, it will survive until it gets
removed from the stack by returning from the method; with a null assignment,
it disappears earlier (but does not necessarily gets collected immediately),
and with a Dispose() you are sure whatever unmanaged resources it holds get
released immediately, without changing the point in time the object itself
becomes unreachable, hence collectable.
|
|
|
|
|
Luc Pattyn wrote: You assign magic powers to the GC; it does not understand your program
Yes, it does. All it has to do is to check where the variables are used. That's not very complicated.
Luc Pattyn wrote: it can't
predict whether an existing reference is still needed or not.
Yes, it can, and it does.
Luc Pattyn wrote: The local ref-type variable is located on the stack (or JIT-optimized into a
register). If it is not null, the object it refers to is alive, even if the
program does not intend to use it any more.
That's not accurate. The object is only alive as long as the reference to it is used. When the garbage collector knows that the referens is not going to be used any more, the reference is no longer considered, and the object is no longer alive.
This can easily be demonstrated with this program:
using System;
using System.Collections.Generic;
namespace TestConsole {
class Program {
static List<WeakReference> refs;
static void Main(string[] args) {
refs = new List<WeakReference>();
byte[] ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, ref10;
ref1 = Create();
ref2 = Create();
ref3 = Create();
ref4 = Create();
ref5 = Create();
ref6 = Create();
ref7 = Create();
ref8 = Create();
ref9 = Create();
ref10 = Create();
int index = 1;
foreach (WeakReference r in refs) {
Console.WriteLine("Item {0} : {1}", index, r.IsAlive);
}
}
static byte[] Create() {
byte[] r = new byte[100000000];
refs.Add(new WeakReference(r));
return r;
}
}
}
When you run it, it will show that only one (at least on my system) of the arrays is still alive. The others have been garbage collected, despite there being specific references to them.
If you try it, be sure to run it in release mode. In debug mode the references are considered active for their entire scope, so that the debugger can show their values.
Luc Pattyn wrote: Now my problem was: why would the compiler actually generate code to assign
null to it, since there is no further use for it; a regular non-CLR compiler
(say a C compiler) would optimize it away immediately. But it seems the C# compiler
designer has not optimized assignments that far that "obj=null;" would be
removed. (Unfortunately he also did not remove useless val-type assignments,
try ending a method on int a=12; and watch its MSIL).
The compiler doesn't do much optimising. Almost all optimising is done by the JIT compiler, so you should look at the actual code generated, not the IL code.
---
single minded; short sighted; long gone;
|
|
|
|
|