|
Thank you!
What I actually wanted to do was to take fixed statements outside a loop. It's because I have discovered, that these statements bring an overhead and, therefore, a performance drop. So, I had an idea to "cache" pinned pointers but I couldn't use a fixed statement when outside a loop. Finally, here is a result:
string[] oldValues,
int oldCount = oldValues.Length;
GCHandle[] oldHandles = new GCHandle[oldCount];
for (int i = 0; i < oldCount; i++)
{
oldHandles[i] = GCHandle.Alloc(oldValues[i], GCHandleType.Pinned);
}
char* oldFix = oldHandles[i].AddrOfPinnedObject();
fixed (char* oldFix = oldValues[i])
This brought about 1.5x performance increase, so it was worth. But still I'm not sure if it is correct (and is hard to detect experimentally due to unpredictability of GC).
Edit: fixed fixed code
Greetings - Jacek
modified 27-Dec-11 13:15pm.
|
|
|
|
|
I don't know, I'm not 100% sure of this, but it looks to be fixing the strings temporarily and not long enough.
Jacek Gajek wrote: but I couldn't use a fixed statement when outside a loop Why is this? I've written plenty of loops spanned by a fixed.
Not that many, granted, but I would say that usually when I use fixed, there is P/Invoke or a loop inside it.
edit: I would only use the GCHandle way to pin if something has to remain pinned for a long time or the pinning must survive returning from the function that pins it in a way that can not be refactored in a sane way (typically these things happen at the same time). Or in the rare case that a GCHandle is required anyway.
modified 27-Dec-11 12:49pm.
|
|
|
|
|
harold aptroot wrote: Why is this? I've written plenty of loops spanned by a fixed.
If you have a single pointer then it is possible. But if you had an array of strings A, then you cannot pull the fixed statement outside the loop since you do not have an indexer:
while(...)
for(int i = 0; i<len; i++)
{
fixed(char* str = A[i])
}
Solution:
GCHandle[] handles= new GCHandle[len];
for (int i = 0; i < len; i++)
{
handles[i] = GCHandle.Alloc(A[i], GCHandleType.Pinned);
}
while(...)
for(int i = 0; i<len; i++)
{
char* str = (char*)handles[i].AddrOfPinnedObject()
}
for (int i = 0; i < len; i++)
{
handles[i].Free();
}
Note: I use memcpy and memcmp inside, so yes there is some P/Invoke shift involved.
Greetings - Jacek
modified 27-Dec-11 13:15pm.
|
|
|
|
|
Oh ok, makes more sense now.
Why is the array pinned too though?
|
|
|
|
|
No special reason. It also caused a fatal exception. Now removed.
Greetings - Jacek
|
|
|
|
|
Sometimes I get "handle is unpinned" exception on AddrOfPinnedObject method call. Any ideas how is it possible? As I see in dotPeek, the exception is thrown because a condition ((int) this.m_handle & 1) != 0; is not satisfied. Since I do not call Free until the method's exit point, I really don't get how was it possible to happen .
Greetings - Jacek
|
|
|
|
|
I don't know, that makes no sense to me.. I would almost say it's a bug in the CLR, but those are rare so I'm probably missing something
|
|
|
|
|
Jacek Gajek wrote: 1.5x performance increase
Compared to what?
And what, exactly, are you trying to accomplish?
|
|
|
|
|
Jacek Gajek wrote: If it is wrong
Probably.
Jacek Gajek wrote: what is an alternative
Set it within the fixed block?
|
|
|
|
|
PIEBALDconsult wrote: Set it within the fixed block?
Thank you for your interest, but I though it was obvious that for some reasons I need another solution than this.
Greetings - Jacek
|
|
|
|
|
Jacek Gajek wrote: I though it was obvious
Obviously not.
|
|
|
|
|
Understanding what you are doing and what you think you are achieving would help.
For example the following might or might not be relevant.
- Allocating a block or pool of blocks at application start and using those over and over might be better than any solution that requires re-allocating over and over.
- If you haven't profiled the application under a correct production model load (not test load) then attempting to optimize anything is futile.
|
|
|
|
|
hello guys... Lets suppose I have a TextBox on this Form1. Now when I resize the form, I want the resize the textbox as well. I have been trying to do this, but have not been able to get the <b>Size</b>, <b>Height </b>or <b>Width</b> property of Form1 in <b>IntelliSense</b>. I have <code>System.Drawing</code> in my code file as well.
|
|
|
|
|
Try Anchor ing it to both sides of the Form.
|
|
|
|
|
Try TextBox1.Width TextBox1.Height or TextBox1.Dock would be better.
Frazzle the name say's it all
|
|
|
|
|
|
In addition to studying Anchor and Dock properties of Controls, as suggested here, you can also use aspects of Padding and Margin to affect the way Controls are positioned ... in relation to other Controls ... and/or in relation to Container Controls they are "placed within."
Note that WinForms, and many Controls, have MaximumSize and MinimumSize properties, that may affect their re-size behavior, depending on how they are anchored/docked, or affected by Margin, or Padding inside Container Controls, and/or in relation to the position of other Controls.
Specifically with a TextBox: I think an important design issue is what the expected content is: how brief, how long ? A single line TextBox is one beast; a MultiLine another ? Under some conditions I would not be concerned with re-sizing a TextBox; under other conditions: yes.
"It is the mark of an educated mind to be able to entertain a thought without accepting it." Aristotle
|
|
|
|
|
On a related note, Bill, how does one go about changing the font size when the size of the textbox changes? Is there a reasonably simple way to calculate the proper font size when the textbox is reduced, perhaps, 50%? Just curious...
Will Rogers never met me.
|
|
|
|
|
I once tried a WinForm experiment where I:
a. in the Form Load event:
1. did a recursive parsing of every Control on the Form, to locate all Controls that had a Font property (Labels, TextBoxes, etc.) that one might want to be changed when the Form was resized.
Each of these selected Controls, and their Font, were stored as Dictionary entries:
private Dictionary<Control, Font> cFontDict = new Dictionary<Control, Font>(); The initial Form Size was then stored.
b. in the Form SizeChanged EventHandler:
1. calculated change ratios in width and height based on the obvious.
2. traversed the Dictionary<control, font="">, via for-loop (so I could alter entries), and messed around with changing the Font based on the calculated change ratios.
WinForms does not make this easy since Control.Font.Size, and Control.Font.SizeInPoints are both read-only properties.
A look at the typical Font assignment code in a Designer.cs file:
this.textBox1.Font = new System.Drawing.Font("Arial", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); Suggests the tediousness involved in changing the whole damn Font just to get a change in FontSize. I did this so long ago I forget exactly how I coded that up.
And what did I end up with: when the app was run, and the Form resized arbitrarily: a lot of bad-looking UI, with the Fonts often looking crummy. I forget whether I limited this to an experiment involving only certain types of Fonts (TrueType ?), or not.
After all, a change in FontSize means you need to have the AutoSize properties of TextBoxes, Labels, etc., set to 'True. And as their "container" size increases or decreases based on new line-height parameters, they then may be out of alignment with other fixed size Controls. So the container itself needs to be scaled.
So, the next step would have been to resize every Control by the same ratios, perhaps address special properties of certain Controls, like the ItemHeight of a ListBox ... but I never took that next step: because, by that time, I had already concluded that reasonable continuous scaling of Fonts in WinForms was a losing proposition, and that if I really had to have that functionality, I should change over to WPF where it appears to me that functionality is ready-to-go out-of-the-box.
The only scenario I can imagine, currently, in WinForms, where I might try to vary FontSize based on the changing Form Size would be one where some client demanded (and was willing to pay for) an App that "snapped" between two or four different sizes, where I could do the right thing, to make all the Fonts that needed to change look good at each size.
best, Bill
"It is the mark of an educated mind to be able to entertain a thought without accepting it." Aristotle
|
|
|
|
|
One major reason for this looking crappy is that Windows picks a screen font with an integer pixel size. If you're resizing from 10 pixel by 85%, it's going to jump to 9, which is too big and your control alignment will be broken, or 8, which is too small and ditto. As you discovered, you can't really do this for UI.
In a real project at the moment I am doing exactly this on a graph, however, and it works pretty well there. That's because the text components (axis labels, captions, headers, value labels) are not aligned with each other in such a way that you notice the slight inconsistencies. I can also see how resizing the font in an individual text area might make sense. Standard control fonts, though, should be left alone because the user has certain expectations about those; even if you got your scaling working perfectly, it would be a nasty user experience.
You can 'scale' a font thus:
Font newFont = new Font(oldFont.FontFamily, newSize);
Ed: I'm not sure if Windows or the Framework caches font objects. If not, you're going to end up with a huge stack of wasted font resources if you implement arbitrary scaling, at least until the GC gets around to collecting them all (which might be a long, long time since you won't be running low on memory which is what it looks at).
|
|
|
|
|
Hi Bob,
Indeed, I would (and have done). once in a while, scale a label where its changing size did not impinge on the overall layout.
Do you find it interesting that the normal WinForms Font size spec written out in the Designer.cs file is a float with a decimal fractional component ?
best, Bill
"It is the mark of an educated mind to be able to entertain a thought without accepting it." Aristotle
|
|
|
|
|
|
when a program becomes very big in source code, its better to write it within 2 or more seperate source code and then compile them
together. question is this thah how can we do it in C#? and how tow
to combine it to other routines. in delphi we do it by units, but I
am novice in c#. please tell me step by step and explicit. tnx
|
|
|
|
|
That's what partial classes are for.
|
|
|
|
|
I think he is not talking about breaking classes into multiple files, rather it is about breaking the logic into multiple classes and packaging them into libraries.
|
|
|
|
|