|
Stephan Samuel wrote: What's behind SoundInitState.GetInstance()? Every time I've written something with an Instance property or a GetInstance(), it's been a singleton.
Correct, that's the case here
Stephan Samuel wrote: Also, what does Stop() do in each of the states?
Just a function where the state will cleanup itself (remove resources etc) before switching to the next state
Stephan Samuel wrote: the GC isn't collecting them
So you suggest to use some sort of structs + switch-calls to keep the memory footprint as small as possible? Or does it help to design my states as normal instances instead of singletons?
modified 12-Sep-18 21:01pm.
|
|
|
|
|
You should keep your states small. Structs won't work because they don't implement inheritance, but try to keep the information inside your concrete state classes to a minimum. I would avoid the singleton pattern for states.
Currently, your states don't really switch. Each tunnels through to the next. There should probably be one top-level controller (it may be a singleton but may not need to be) that decides which state you're in and runs the states:
(Please pardon any typos or syntax errors; I'm making this up as I go.)
<br />
public class MyController<br />
{<br />
State currentState;<br />
<br />
public void RunMe()<br />
{<br />
while (this.currentState != null)<br />
this.currentState = this.currentState.RunMe();<br />
}<br />
}<br />
<br />
public abstract class State<br />
{<br />
public abstract State RunMe();<br />
}<br />
<br />
public class ConcreteState1()<br />
{<br />
public RunMe()<br />
{<br />
return new ConcreteState2();<br />
}<br />
}<br />
<br />
public class ConcreteState2()<br />
{<br />
public RunMe()<br />
{<br />
return null;<br />
}<br />
}<br />
Likely, you'll want to pass around some objects, and your states will pass out different "next state" objects as RunMe() returns based on what those objects look like. Each state lives only as long as it's executing, so there's no memory overhead. If you're worried about setup/tear-down performance of your state objects (e.g. -- if they have a complicated DB open process and you need them to run really quickly with persistent connections), consider some level of factory for the states: either have a connection factory, give each state its own factory and let it decide when to create a new one of itself, or create a factory class (or implement one in MyController) that decides the lifetime of your state objects.
I'd also implement IDisposable and the C# disposal pattern for each of your state objects to clear up unmanaged resources. Managed resources should get cleaned up automatically.
The other way to implement this is to have MyController decide which state is next based on the state of some object. My personal belief is that method isn't as good. It's less OO: you might as well just code all the possibilities within the controller and forget the states.
|
|
|
|
|
Great. The Controller object really makes sense and keeps memory overhead at a minimum, that's a really good way, I like. The only addition I will make is to keep a Stack<State> in my controller, so that some states will still be able to overlap each other, like a menu on top of a game.
Thanks a bunch!
modified 12-Sep-18 21:01pm.
|
|
|
|
|
As you are switching from state to state by using a method in each object, the objects can't be garbage collected. The Switch method of each previous state is still executing until the last state is finished. When the last state returns from the Switch method, all previous Switch calls will finish in turn and release the objects.
This is not a problem, however, as long as you make the Stop method release all objects contained in it's state object.
---
b { font-weight: normal; }
|
|
|
|
|
Guffa wrote: This is not a problem, however, as long as you make the Stop method release all objects contained in it's state object.
That's what I do. So the only thing left in memory will be the instance of the state objects and nothing more? I hope this isn't too much overhead as a drawback for clean design.
modified 12-Sep-18 21:01pm.
|
|
|
|
|
Greeeg wrote: So the only thing left in memory will be the instance of the state objects and nothing more?
If you get rid of all references in the object (setting them to null), all objects that it used are up for garbage collection. If the memory is needed, they will be collected.
---
b { font-weight: normal; }
|
|
|
|
|
Hello,
In order to show users a string representation of a 120kb file in Hex-format within a windows forms textbox I wrote a simple routine that converts all decimal bytes in a buffer into a hexadecimal string, taking formatting into account. The routine looks like this:
<br />
int x =0;<br />
<br />
string content = String.Format("\n{0:X5}: ", x);<br />
<br />
for (; x < Data.senderdata.Length; x++)<br />
{<br />
content += String.Format("{0:X2}", Data.senderdata[x]);<br />
<br />
#if DEBUG<br />
flp.setProgress(0, Data.senderdata.Length, x);<br />
#endif<br />
<br />
if ((x + 1) % 2 == 0) content += " ";<br />
if ((x + 1) % 16 == 0) content += String.Format("\n{0:X5}: ", (x+1));<br />
}<br />
When done, the content string is assigned to a textbox control. Perhaps I should mention "senderdata" is a byte array.
The routine seems to take an insane amount of time to complete. I realize that it might take a few secconds, since senderdata.Length typically has a value of about 125K, but this is taking over a minute to complete, in a single threaded program running on a pentium 4. Is this due to the String.Format Hex-conversion routine or is it just that it's too hard for Windows to handle such long strings? Does anyone have a tip to improve on the performance of this?
Thanks in advance for any help,
Benny
|
|
|
|
|
One possible suggestion is, you could replace the variable type of content, from string to StringBuilder instance.
StringBuilder's concatenation are faster than string's.
-- modified at 9:48 Tuesday 6th June, 2006
|
|
|
|
|
Thanks very much (Stefan aswell), this helps alot
|
|
|
|
|
I think a main issue is the mass number of string concatenation. As a string is immutable , a new string object is created everytime you append something to your content variable. Try using StrinBuilder[^] instead.
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook
www.troschuetz.de
|
|
|
|
|
When the += operator is used on a string, it might appear like the string is appended to the end of the original string. This is not true, as strings are immutable in .NET.
The statement:
content += " ";
is actually performed as:
content = string.Concat(content, " ");
With that in mind, let's do some math to find out why the routine is so slow:
Each iteration does either one, two or three concatenations. The first one is done every iteration, the second is done every other iteration, and the third is done every 16th iteration.
This gives that:
:: Each iteration does by average 1.5625 string concatenations.
:: Each iteration adds by average 3.0625 characters to the string.
With an array containing 125000 elements it produces a string that contains about 383000 characters. As each character is two bytes, that gives a string that uses 766 kbyte of data.
As the string is growing in a linear fashion, we can calcuate the average work done by each concatenation by taking the average size of the string during the operation, which is half the size of the finished string.
So a concatenation is by average moving an amount of 383 kbytes of data. As we have 125000 iterations, we have around 195000 string concatenations (125000 times 1.5625). 195000 times 383 kbytes makes 74685000 kbyte.
When the routine has finished, it has moved somewhere around 75 gigabyte of data. (As that is far more than the amount of avialable RAM, this has also caused hundreds of garbage collections to take place.)
That is the reason why the routine is so slow.
To improve the routine is easy. Use a StringBuilder. That would make the routine run around a 100000 times faster.
As an interresting observation in optimization, one can speed up the routine somewhat by using a temporary string:
string content, line;
content = string.Empty;
line = string.Empty;
for (int x = 0; x < Data.senderdata.Length; x++) {
if (x % 16 == 0) {
content += line;
line = String.Format("\n{0:X5}: ", (x+1));
}
line += String.Format("{0:X2}", Data.senderdata[x]);
if ((x + 1) % 2 == 0) line += " ";
}
content += line;
This would redude the number of lengthy concatenations from 1.5625 per iteration to 0.0625, reducing the execution time by 96%. Not nearly as effective as using a StringBuilder, but somewhat impressive eventhough...
---
b { font-weight: normal; }
-- modified at 11:27 Tuesday 6th June, 2006
|
|
|
|
|
I need leave my textBox control only if I press three times the Tab key. I use this:
<br />
private void KKEditControl_Leave(object sender, EventArgs e)<br />
{<br />
this.Focus();<br />
}<br />
but it keeps focus in my textBox all the time. Please help me...
|
|
|
|
|
You need to count how much times he leaves.
try this:
<br />
int NumLeaves = 1;<br />
private void KKEditControl_Leave(object sender, EventArgs e)<br />
{<br />
if (NumLeaves%3 != 0)<br />
this.Focus();<br />
NumLeaves++;<br />
}<br />
This should work.
|
|
|
|
|
I tried to count but in different way - it doesn`t work.
Your way works great!
Thanks a lot!
|
|
|
|
|
i get a exception when i show a form
the exception is the "object is currently used elsewhere :
i dont get these kind of exception when i call a form by creating an object
what is the reason
|
|
|
|
|
Hello!
I am trying to implement a simple drag&drop ability for a ListView. It should just get the text of the selected subitem and drag its text. I tried this:
private void OnDataListItemDrag(object sender, ItemDragEventArgs e)
{
ListViewItem lvi = e.Item as ListViewItem;
if(lvi == null) return;
string strDrag = lvi.Text;
this.DoDragDrop(strDrag, DragDropEffects.Copy | DragDropEffects.Move);
...
The problem now is that the code above always gets the text of the item, not of the subitem. But the user should be able to drag cells, i.e. the subitems. The ItemDragEventArgs structure doesn't seem to have a SubItem member. I also cannot use HitTest here, as the mouse cursor position is incorrect at that time (user dragged the item already a few pixels before the event above is fired, therefore a hit test at that time could result in an incorrect item or column).
Any idea how to get the dragged subitem?
Many thanks in advance and best regards
Dominik
_outp(0x64, 0xAD);
and
__asm mov al, 0xAD __asm out 0x64, al
do the same... but what do they do??
(doesn't work on NT)
|
|
|
|
|
HI
I have a problem which is I need to know if I am connected to the internet or not... how I could do this through the code
so please help me
Tamimi - Code
|
|
|
|
|
Use TcpClient :
try
{
System.Net.Sockets.TcpClient tcpClient = new System.Net.Sockets.TcpClient();
tcpClient.Connect("www.microsoft.com", 80);
Console.WriteLine("Connected to internet");
}
catch(Exception ex)
{
Console.WriteLine("Not connected to internet");
}
|
|
|
|
|
its does not work , iam connected through a LAN.
does this mean anything ??
thank you
Tamimi - Code
|
|
|
|
|
That code works only if you are connected directly to internet.
If you have a proxy, then you must search for an article in
codeproject about using TcpClient with Proxy or WebRequest
using Proxy.
|
|
|
|
|
If you are connected via LAN, then you should always be connected, unless you only have a local INTRANET, which would explain why you couldnt get through. The code supplied would be a valid way to check for connection, however.
Aaron
|
|
|
|
|
I want to change the keyboard layout using c#, so i can write in arabic inside the text box.
In VC++ we used LoadKeyboardLayout what we use in C#
THanks
|
|
|
|
|
Use this is your code :
[DllImport("user32.dll")]
static extern IntPtr LoadKeyboardLayout(string pwszKLID, uint Flags);
|
|
|
|
|
hi all,
i have a button which binds some data to each other.
but if i double click on that button, i receive an error which says a previously binding exists.
how can i avoid this error ?
i mean: am i able to check if there is a databinding exists when i click on that button ? or am i able to collapse(or purge) the previously databinding when i click on that button ?
|
|
|
|
|