I wrote a custom control in C# that inherits from the RichTextBox. The purpose of this control is to contain all improvements and changes, such as modified line numbering and having the control repaint itself only when it should.
Yesterday, I noticed memory spikes (and often, OOM exceptions) when accessing the Lines property of this control (there are 600,000+ lines in the control at times). I coded workarounds that no longer involve it, but I would still like to completely remove it so people who use my control in the future do not use it.
The Lines property is System.Windows.Forms.TextBoxBase.Lines. Ideally, I'd like the string[] for this property to never be touched; when I load text in the control, I do NOT want the control to do anything to fill this lines property (because it's completely pointless and is consuming some time and resources).
Anyone have any ideas?
EDIT: I tried
public override string[] Lines
{
get { return null; }
set { ; } // do nothing
}
But VS says "cannot override inherited member System.Windows.Forms.TextBoxBase.Lines.get because it is not marked virtual, abstract, or override.
So it looks like I can't override or remove it. I think the RichTextBox is setting the property because it is filled after change the text. Is there a way for me to capture and handle that message?
Hmya, it is only going to slow down a decent programmer for no more than 5 minutes:
string[] lines = ((RichTextBox)myEditor1).Lines;
which will blow just as hard. There isn't much point in trying to prevent usage of your class that can be used anyway. The Lines property ought to be useful to anybody that uses your editor, it covers the very basic need to be able to retrieve the text that was edited. Don't throw out the baby with the bath water.
The real problem here is that RTB uses so much unmanaged memory to store the text, leaving little left for the garbage collected heap. It gets really slow too once you pump thousands of lines into it. No component should ever be allowed to swallow up half of all available memory. Either limit the number of lines you allow to edit or use a better editor, like ScintillaNET.
It is also rather important to be a pragmatic programmer. Beyond hiding a property needlessly. 600,000 lines in a text box is an enormous number. There a 3/4 million words in the Bible, you are displaying 6 copies of the Bible in your text box. No sane human is ever going to read that, they'll just dislike your program intensely. Not just because it is impossible to use effectively but also because it is a crash bucket.
Have you tried to shadow the property?
public new string[] Lines
{
get { throw new Exception("Not supported"); }
set { throw new Exception("Not supported"); }
}
Related
My question is to how to split into multiple files a method containing an override?
I understand that this is not possible with partial.
In my code, I have too much lines in this method. I code on the QuantConnect platform that limits the size of one file, and I reach this limit.
public partial class TestAlgo : QCAlgorithm
{
public override void OnData(Slice slice) // Name OnData can't be modified.
{
Indices:
{
//First Indices
}
{
//Second Indices
}
...
}
}
Unfortunately, this is not possible. You should refactor your code so that you split your method into multiple methods instead, and then you could use partial, though I'm still not sure why you'd want to do that rather than refactoring complex code into multiple classes.
It says right there in the documentation:
Partial methods are implicitly private, and therefore they cannot be virtual.
More to the point, even with non-virtual methods, partial doesn't allow you to split the method body itself across multiple files. It's just a way of allowing one file to declare the method and another to provide the implementation.
So, we should focus on this part of your question, rather than the XY Problem you've asked about:
I have too much lines in this method. I code on the QuantConnect platform that limits the size of one file, and I reach this limit.
Whatever the limit of the size of the file, I would guess it's a reasonably generous limit. If you've reached that limit as a result of a single method, then you have way too much code in that method.
There are lots of guidelines about how many lines of code a method should have. They are fairly subjective in nature. People debate whether it's "one screen" or "two screens" or something else. But it's safe to say that you've gone way beyond this.
Your method really needs to be refactored into smaller pieces. Probably into smaller classes. How exactly to do that, can't be answered here because you haven't provided that context. But, it needs to be done.
This is the first time I face a problem like this. Not being this my profession but only my hobby, I have no previous references.
In my program I have added one by one several functions to control a machine. After I added the last function (temperature measurement), I have started experiencing problems on other functions (approx. 8 of them running all together. The problem I am experiencing is on a chart (RPM of a motor) that is not related to this function but is affected by it. You see the difference between these two charts with and without the temperature measurement running. The real speed of the motor is the same in both charts but in the second one I loose pieces on the fly because the application slows down.
Without the temperature function.
With the temperature function
Particularly this function is disturbing the above control and I think is because the work load is becoming heavy for the application and or because I need sampling so there is some time waiting to get them:
private void AddT(decimal valueTemp)
{
sumTemp += valueTemp;
countTemp += 1;
if (countTemp >= 20) //take 20 samples and make average
{
OnAvarerageChangedTemp(sumTemp / countTemp);
sumTemp = 0;
countTemp = 0;
}
}
private void OnAvarerageChangedTemp(decimal avTemp)
{
float val3 = (float)avTemp;
decimal alarm = avTemp;
textBox2.Text = avTemp.ToString("F");
if (alarm > 230)
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer();
player.Stream = Properties.Resources.alarma;
player.Play();
timer4.Start();
}
else
{
timer4.Stop();
panel2.BackColor = SystemColors.Control;
}
}
I am wondering if running this function on a different thread would solve the problem and how I can do that? Or if there is a different way to solve the problem.Sample code will be appreciated.
Update, added method call.
This is how I call the method AddT
if (b != "")
{
decimal convTemp; //corrente resistenza
decimal.TryParse(b, out convTemp);
AddT(convTemp);}
This is how I receive the data from the serial and pass it to the class that strips out unwonted chars and return values to the different variables.
This is the class that strips out the unwonted chars and return the values.
And this is how I manage the serial incoming data. Please do not laugh at me after seeing my coding. I do a different job and I am learning on my own.
It's very hard to tell if there's anything wrong and what it might be - it looks like subtle problem.
However, it might be easier to get a handle on these things if you refactor your code. There are many things in the code you've shown that make it harder than necessary to reason about what's happening.
You're using float and decimal - float isn't that accurate but small and fast; decimal (tries) to be precise but especially is predictable since it rounds errors the way a human might in base-10 - but it is quite slow, and is usually intended for calculations where precise reproducibility is necessary (e.g. financial stuff). You should probably use double everywhere.
You've got useless else {} code in the Stripper class.
Your Stripper is an instatiable class, when it should simply be a static class with a static method - Stripper is stateless.
You're catching exceptions just to rethrow them.
You're using TryParse, and not checking for success. Normally you'd only use TryParse if you (a) expect parsing to fail sometimes, and (b) can deal with that parse failure. If you don't expect failure or can't deal with it, you're better off with a crash you learn about soon than a subtly incorrect values.
In stripper, you're duplicating variables such as _currentMot, currentMot, and param4 but they're identical - use only the parameter, and give it a logical name.
You're using out parameters. It's almost always a better idea to define a simple struct and return that instead - this also allows you to ensure you can't easily mix up variable names, and it's much easier to encapsulate and reuse functionality since you don't need to duplicate a long call and argument definition.
Your string parsing logic is too fragile. You should probably avoid Replace entirely, and instead explicitly make a Substring without the characters you've checked for, and you have some oddly named things like test1 and test2 which refer to a lastChar that's not the last character - this might be OK, but better names can help keep things straight in your head too.
You have incorrect code comments (decimal convTemp; //corrente resistenza). I usually avoid all purely technical code comments; it's better to use descriptive variable names which are another form of self-documenting code but one in which the compiler can at least check if you use them consistently.
Rather that return 4 possibly empty values, your Stripper should probably accept a parameter "sink" object on which it can call AddT AddD and AddA directly.
I don't think any of the above will fix your issue, but I do believe they're help keep your code a little cleaner and (in the long run) make it easier to find the issues.
your problem is in the parsing of the values you have
decimal.TryParse(a, out convRes);
AddA(convRes);
and don't check for failed values you only accept the value if it returns true
if(decimal.TryParse(a, out convRes))
{
AddA(convRes);
}
you may have more errors but this one is making you process 0 values every time the TryParse fails.
I'm writing small C# application mainly for fun, and there is a DataGridView to show some data, it is bound to the BindingList. Fun started from the moment I decided to make the table sortable, that's the reason for using BindingList. As far as I understand, there's no standard implementation of this in the BindingList, but msdn has the article covering this (about implementing sort and find for BindingList). Long story short, few lines in their implementation that cause troubles:
SomeClass tmp;
for(...)
{
tmp = this[i]; //fast
this[i] = this[position]; //slow
this[position] = tmp; //slow
}
As comments show, the first assignment doesn't take much time, but other two are really slow. I fail to understand the reason behind it, but because of it sorting list 50 or so elements takes about two seconds.
Well, I can use some workaround, but it seems to be a bit ugly. Besides, I really want to know what causes such behavior.
The slow down happens because the assignment will cause anything that is bound to that list to redraw (for example, the DataGridView).
You should modify your sort method to disable raising events while the list is being changed.
var origRaiseEvents = this.RaiseListChangedEvents;
this.RaiseListChangedEvents = false;
try
{
// here goes your original code.
}
finally
{
this.RaiseListChangedEvents = origRaiseEvents;
}
The main issue, if this is a BindingList, is that the DataGridView will try to update every time you set anything within your BindingList. This means the two lines that you marked as slow are most likely not slow themselves, but slow because they trigger the DataGridView to refresh, which means it's refreshing many times over the sort operation.
You could get around this by encapsulating the BindingList instead of subclassing it, and not raising the events during the sort, but wait until the sort is completed, then refresh the entire list.
I'm programming for a game in XNA and attempting to create a universal math object with a stored output location supplied during construction.
My plan was to use ref in the constructor, but I'm not sure how to hold/store that reference in the object beyond the initial call...
public MathObject(ref float OutParam)
{
Out = OutParam; // This obviously won't do what I want... But it's where I'd like to do it.
}
In the update I'd like to state the input and have the product modify the stored output location:
foreach (MathObject MatOb in MathList)
{
MatOb.Update(time);
}
The idea was to create a modular math tool to use throughout the code and direct it on creation to a pre-existing object parameter elsewhere ("output") that it will modify in the update (without re-referencing). The hope was that this would allow a single loop to direct every instance of the tool to modify it's given output.
As I understand it, in c++ this is possible through storing the address of the parameter to be modified within the math object, then using this in the update to point to and modify the memory at that location.
Is something similar possible in c# without the use of unsafe code?
Should unsafe code always be avoided?
Edit:
-- Intended Use --
I'd like to be able to create objects with an adjustable "set and forget" output location.
For instance, I've built a simple bezier curve editor that works within the game interface. I can set the output locations in the code so that a given curve always adjusts specific parameters(character position for example), but It would be nice to modify what the output is connected to within the interface also.
The specific applications would be mostly for in-game editing. I understand editors are most practical when self-contained but this would be for limited, game console friendly editing functionality (less robust, but similar in principle to the editing capablities of Little Big Planet).
My background is in 3D design and animation so I'm used to working with many node-based editing systems - Creating various utility nodes and adjusting inputs and outputs to drive parameters for shading, rigging models, etc. I'm certainly not attempting to re-create this in game, but I'm curious about carrying over and applying certain principles to limited in-game editing functionality. Just troubleshooting best to go about it.
Thanks for the replies!
The way to do this in C# is to use a pair of get/set delegates. You could use this handy-dandy helper struct to store them:
public struct Ref<T>
{
Func<T> get;
Action<T> set;
public Ref(Func<T> get, Action<T> set)
{
this.get = get;
this.set = set;
}
public T Value { get { return get(); } set { set(value); } }
}
Given some class like this:
class Foo { public float bar; }
Use it like this:
Foo myFoo = new Foo();
Ref<float> barRef = new Ref<float>(() => myFoo.bar, (v) => myFoo.bar = v);
// Ta-Da:
barRef.Value = 12.5f;
Console.WriteLine(barRef.Value);
(Please note that I haven't actually tested the code here. The concept works and I've successfully used it before, but I might have messed up my syntax by typing this up off the top of my head.)
Because this question is tagged with XNA, I should briefly talk about performance:
You'll probably find this performs about an order of magnitude or so slower than the equivalent memory access - so it's not suitable for tight loops.
Creating these things allocates memory. This is very bad for performance for a number of reasons. So avoid creating these inside your draw/update loop. During loading is fine, though.
And, finally, this is uglier than simply accessing the property directly - so be sure that you're doing what you can to avoid using this where possible.
I wouldn't know how to do this in C# without unsafe code, but.. if you absolutely must tackle your problem with this solution and without using unsafe code then maybe memory mapped files are your friend. even so, these haven't been around for .NET development until .NET 4.0 and I'm not sure how this option compares to unsafe code performance-wise.
I think what you need is the observer design pattern. Item interested in the update of math object will register the avent ( ie MathObjectChange ) and react properly.
I know it sounds really stupid, but I have a really easy application that saves some data from some users on a database, and then I want to write all the data on a .txt file.
The code is as follows:
List<MIEMBRO> listaMiembros = bd.MIEMBRO.ToList<MIEMBRO>();
fic.WriteLine("PARTICIPACIONES GRATUITAS MIEMBROS: ");
mi = new Miembro();
foreach (MIEMBRO_GRATIS m in listaMiembroGratis)
{
mi.setNomMiembro(m.nomMiembro);
mi.setNumRifa(m.numRifa.ToString());
fic.WriteLine(mi.ToString());
}
fic.WriteLine();
As you see, really easy code. The thing is: I show the information on a datagrid and I know there are lots of more members, but it stops writing in some point.
Is there any number of lines or characters to write on the streamwriter?? Why I can't write all the members, only part of them???
fic is probably not being flushed by the time you are looking at the output file; if you instantiate it as the argument for a using block, it will be flushed, closed, and disposed of when you are done.
Also, in case you are flushing properly (but it is not being flushed by the time you are checking the file), you could flush at the end of each iteration:
foreach (MIEMBRO_GRATIS m in listaMiembroGratis)
{
mi.setNomMiembro(m.nomMiembro);
mi.setNumRifa(m.numRifa.ToString());
fic.WriteLine(mi.ToString());
fic.Flush();
}
This will decrease performance slightly, but it will at least give you an opportunity to see which record is failing to write (if, indeed, an exception is being thrown).
Is there any number of lines or characters to write on the
streamwriter??
No, there isn't.
As you see, really easy code. The thing is: I show the information on
a datagrid and I know there are lots of more members, but it stops
writing in some point
My guess is that your code is throwing an exception and you aren't catching it. I would look at the implementation of setNomMiembro, setNumRifa and ToString in Miembro; which, by the way, in the case of setNomMiembro and setNumRifa should probably be implemented as properties ({get;set;}) and not as methods.
For example, calling ToString in numRifa would throw a null pointer exception if numRifa is null.