|
Look at the code: the are two similar methods. One declares all variables used in the method at the start of the method, the other one declares them when it needs then. May there be any lower CPU or memory cost in the second version of the method (the one at the bottom) ?
<br />
public void DoSomethingComplex(...)<br />
{<br />
int[] intarray = new ...<br />
bool somecondition = ...<br />
if (somecondition == true)<br />
intarray[1].Add ...
}<br />
<br />
public void DoSomethingComplex(...)<br />
{<br />
bool somecondition = ...<br />
if (somecondition == true)<br />
{<br />
int[] intarray = new ...<br />
intarray[1].Add ...
}<br />
}
Regards, Desmond
|
|
|
|
|
It's not really the declarations of things you have to worry about in general from a performance perspective; it's the allocation of things. Check this out:
<br />
using System;<br />
<br />
class Test {<br />
<br />
<br />
public static void DoSomethingComplex(bool _someCondition) {<br />
int[] intArray;<br />
<br />
if (_someCondition) {<br />
intArray = new int[100];<br />
}<br />
<br />
}<br />
<br />
static void Main(string[] args) {<br />
DateTime startTime, endTime;<br />
int millisecondCount;<br />
int loopCount = 100000;<br />
<br />
startTime = DateTime.Now;<br />
for(int x = 0; x < loopCount; x++) {<br />
DoSomethingComplex(true);<br />
DoSomethingComplex(true);<br />
DoSomethingComplex(true);<br />
DoSomethingComplex(true);<br />
DoSomethingComplex(true);<br />
DoSomethingComplex(true);<br />
DoSomethingComplex(true);<br />
DoSomethingComplex(true);<br />
DoSomethingComplex(true);<br />
DoSomethingComplex(true);<br />
}<br />
endTime = DateTime.Now;<br />
millisecondCount = ((int)(endTime.Ticks - startTime.Ticks)) / 10000;<br />
Console.WriteLine(millisecondCount + " milliseconds" );<br />
<br />
startTime = DateTime.Now;<br />
for(int x = 0; x < loopCount; x++) {<br />
DoSomethingComplex(false);<br />
DoSomethingComplex(false);<br />
DoSomethingComplex(false);<br />
DoSomethingComplex(false);<br />
DoSomethingComplex(false);<br />
DoSomethingComplex(false);<br />
DoSomethingComplex(false);<br />
DoSomethingComplex(false);<br />
DoSomethingComplex(false);<br />
DoSomethingComplex(false);<br />
}<br />
endTime = DateTime.Now;<br />
millisecondCount = ((int)(endTime.Ticks - startTime.Ticks)) / 10000;<br />
Console.WriteLine(millisecondCount + " milliseconds" );<br />
<br />
}<br />
}<br />
|
|
|
|
|
The second version is better since you allocate the memory only if
if (somecondition == true)
Howver you can do the following:
<br />
public void DoSomethingComplex(...)<br />
{<br />
int[] intarray;
bool somecondition = ...<br />
if (somecondition == true)<br />
intarray = new ...
intarray[1].Add ...<br />
}
|
|
|
|
|
Unless you are into really performance critical applications (and if you are, why aren't you using C++?) I think good coding style and design is generally more important than worrying about how questions like this.
I prefer to declare locals at the point where I going to use them, not detached at the head of the function. To me this localises the use of the variable, and is just better style. Anyway, we shouldn't try to second guess the compiler - for all we know, the compiled code is near identical in both cases.
|
|
|
|
|
Hi,
I would like to send data from one instantiation of class to a textbox in my Form.
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
.
.
}
public class AnotherClass
{
public void SomeMethod(String msg)
{
Form1.textBox1.Text = msg;
}
}
I have tryed setting the textBox1 public. I have try creating an accessor method. But no luck.
Any comments or suggestions would be very welcome.
Thanks in advance.
Jack
|
|
|
|
|
That isn't exactly proper programming practice. It could be done, but really, ALL your code for manipulating the controls on the form should be done on the form, not in a class that doesn't (shouldn't) know what a form is.
If all you doing is what it's your example, that code really shouldn't be in a seperate class. In order for it to work, you'd have to also pass a reference to the textbox to the SomeMethod function.
public void SomeMethod(ref TextBox tbToModify, String strMessage)
{
tbToModify.Text = strMessage;
}
RageInTheMachine9532
|
|
|
|
|
I want to write a application it like Microsoft's PowerPoint User interface..
when user add a new file my application can new a file but the file is adding to other form and can scroller to view and edit others file just like powerpint
how can i write the application or where has similar code...
please help me....thanks
|
|
|
|
|
You can add Microsoft PowerPoint Object Library to your project and use its powerpoint functionality. You can do it by add refrence-->CoM tab.
Mazy
"A bank is a place that will lend you money if you can prove that you don't need it." - Bob Hope
|
|
|
|
|
sorry...i just want a interface like powerpoint which can satisfy my need.(can add a new file to a new form and can scroll up and down all forms just like powerpoint)
I do want't just use a powerpoint component....
everyone please help...thanks your ideas~~~
|
|
|
|
|
|
I am looking for a good book that explores .net diagnostics in depth such as topics about Tracing, Listeners, Event Logs etc. in .NET. Does anyone have any suggestions? I can't find any so far.
Mark Sanders
|
|
|
|
|
See the Microsoft Patterns and Practices[^] section. They have books available for download as PDFs (you can also buy them as books, but the PDFs are complete). One or two go into depth with instrumenting your application, like the Enterprise Instrumention block.
As far as trace listeners, the documentation for the TraceListener in the .NET Framework SDK should be sufficient. There isn't much you can do with these, though, which is where the EI comes into play.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I have my multi-threaded plugin app that I wrote. In the dispose method of a plugin if I issue a Application.Exit it exits both the plugin and the parent app.
Is this normal, seems kinda strange to me...
Matthew Hazlett
Windows 2000/2003 MCSE
Never got an MCSD, go figure...
|
|
|
|
|
Um, this is what it's supposed to do. That's why it's Application.Exit . Read the documentation.
Besides, you don't need to exit anything when your plugin is disposed. The reference object is freed. You really don't even need to implement IDisposable unless you have native resources or other resources you want cleaned up. This is how a garbage collection platform - like .NET and Java - work.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi folks
I've got an array that i am using as a refference to COM that will store the IntPtr's returned from the IEnumID.
<br />
[PreserveSig]<br />
int Next(<br />
int celt,
[MarshalAs(UnmanagedType.LPArray, SizeConst = 100)]<br />
IntPtr[] rgelt,
out int pceltFetched);
While i have it marshaling as an LPArray, the problem i face is that the pointer points to the first element (as far as I can see), and while, forwarding this array to the Next produces a new result (Assumably the next folder in the enumeration), it is only ever allocated to the first possition. The values for the celt increments properly, but the pCeltFetched is always equal to 1 after the first method call.
Am I marshaling it incorectly? I've tried using SafeArray with an IntPtr type, but the compiler keeps spitting it out.
I know that they are marshaled as in only by default, but is there some special handling procedure for selecting the index that the array should begin at?
I have also tried converting the array to a unmanaged structure, so that i can simply use a pointer to handle it, instead of marshaling to and from managed code with each call. However, i get null pointer exceptions, and it's not liking it. I'm calling like this:
IntPtr[] EnumerationArray = new IntPtr[100];<br />
IntPtr ArrayHandle = IntPtr.Zero;<br />
Marshal.StructureToPtr(EnumerationArray, ArrayHandle,true);
Cheers
Cata
|
|
|
|
|
Hi, I don't know the answer to your question, but this 10 minute MSDN video[^] could very well provide the information you need to solve the problem yourself. It discusses the different ways that items are marshalled in platform invoke calls, though not specifically about COM.
BTW, assuming I knew the answer to your problem, it would be difficult to answer your question without also knowing what the COM interface actually expects. You've only listed the part that isn't using the interface correctly. [edit]I might have assumed incorrectly there, if you are referring to the common enumeration interfaces that COM defines.[/edit]
John
"You said a whole sentence with no words in it, and I understood you!" -- my wife as she cries about slowly becoming a geek.
|
|
|
|
|
This is how it is written in C:
HRESULT Next(
ULONG celt,
LPITEMIDLIST *rgelt,
ULONG *pceltFetched
);
where celt is the number of items in the array that is forwarded.
rgelt is a pointer to the array.
pceltFetched is a pointer to a value that holds the number of elements in the returned array.
I shall check this video out.
Cheers
Cata
|
|
|
|
|
That's the way it's supposed to work. Read the documentation in the Platform SDK for IEnumXXXX . It's just like an IEnumerator in .NET, only COM's IEnumXXXX implementations can fetch multiple results depending on what you pass into celt (the first param to Next ). If you know the size of the object (like an ITEMIDLIST , which you can get with Marshal.SizeOf ), you can get the offset the address and get the next object in the array using other methods in the Marshal class, or using an unsafe context.
Another way would be to create an array of ITEMIDLIST (or whatever struct you need, so long as it's defined and attributed properly) and pin the object to gets its address like so:
ITEMIDLIST[] items = new ITEMIDLIST[40];
GCHandle handle = GCHandle.Alloc(items);
int len;
iEnum.Next(items.Length, handle.AddrOfPinnedObject(), out len);
handle.Free(); Then you should be able to access the elements of the array with managed code.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hmmmm.
Maybe i've misinterpreted what i read.
I was under the assumption that the array that i hand to the Next object, is something akin to a stack that new PIDL's are added too, and the celt is the number of items currently on the array, or the index at which the next PIDL is added.
Seems kind of dumb now i think about it.
The PIDL that i am getting back in the first part of the array (I only get one PIDL at a time), is the one i'm looking for?
Can i continuously increment next, and store the PIDL in a purely managed array?
Cheers
Cata
|
|
|
|
|
The Catalyst wrote:
Can i continuously increment next, and store the PIDL in a purely managed array?
Sure. Why not? You should use a list, though, since you'd have to resize the array yourself, or use any length property that the enum might have.
The Catalyst wrote:
I was under the assumption that the array that i hand to the Next object, is something akin to a stack that new PIDL's are added too, and the celt is the number of items currently on the array, or the index at which the next PIDL is added.
Nope. The first param is how large the array is. Since an array is just a pointer, you have to tell native APIs how many elements are in that array so it can use offsets to fill the addresses. This is true of any native API that uses arrays (even character arrays like LPTSTR).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks Heath, most helpful. I was planning on using an arraylist.
One more question.
I'm running my call through Next, like this:
IntPtr[] EnumerationArray = new IntPtr[10];<br />
int ArrayLengthIn = 10;<br />
int ArrayLengthOut = 0;<br />
<br />
ContentEnumeration.Next(ArrayLengthIn,EnumerationArray,out ArrayLengthOut);
But I only ever get a single value returned.
I'm not sure why this is, as i know that there is more than 1 folder on my C drive. I'll have a play with one of the pointers i get back from the array, but can you see any reason why it's only returning a single value?
Cata
|
|
|
|
|
COM requires the address of the first element of an array. IntPtr is the managed representation of that address. The COM implementation doesn't care about arrays, only that address, so declaring the method to accept an array and passing an array in does not matter - it's only going to assign the address of the first array element in its implementation. You need to offset that address to get additional elements, which the Marshal class (or unsafe code) can help with.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
AWESOME! Thanks DUDE!
I got it enumerating properly.. well... i got a sub folder name without it crashing, exploding, or whatever. I'll worry about getting multiple PIDL's later.
One thing is confusing me though.
My StrRetToStr, while working, does odd stuff. 0 seems to be the value that works, but in COM it's supposed to be 1-3. Is this because i'm using signed ints?
Also, my StrRetToStr method refuses to work with a string base type, no matter how I marshal it. But if i change it to a pointer, process it, and change it back, it works fine. I know it's trivial, but i don't understand why it's doin it, and it's bugging me.
Again, thanks for all your help. While i know i've got a long way to go, it's another step towards me grasping COM more completely. *grin*
Cheers!
Cata
|
|
|
|
|
The Catalyst wrote:
While i know i've got a long way to go, it's another step towards me grasping COM more completely.
You REALLY need to learn COM first. Thinking you'll learn COM through .NET Interop is really a naive assumption. Learn COM first - it's difficult enough. You clearly don't understand as much about marshaling as you should. Write a few COM applications first and pick up a good book on COM. You need to know both .NET and COM appart from each other before interop'ing the two. That's pretty much a universal truth.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I've been playing with the GCHandle class, and trying to get a full array, but still not having any joy with it. The array still contains only one entry when it is returned.
IntPtr[] EnumerationArray = new IntPtr[10];<br />
GCHandle handle = GCHandle.Alloc(EnumerationArray, GCHandleType.Pinned);<br />
<br />
int ArrayLengthOut;<br />
<br />
ContentEnumeration.Next(EnumerationArray.Length,handle.AddrOfPinnedObject(),out ArrayLengthOut);<br />
<br />
handle.Free();<br />
<br />
IntPtr pTest = EnumerationArray[0];
Where can i look for information on manualy offsetting arrays? I understand how it's done in structs.
Cata
|
|
|
|