|
|
If there's a way to do it I haven't found the syntax.
|
|
|
|
|
My assumption is that the answer for this is that you cannot have a generic event for the same reason you cannot have a generic field in a non-generic class (or of a generic type that is not a type parameter for the class containing the field). If this was allowed, your class would have to vary in size depending on how many different events were used by external code, which of course is not allowed.
The best option that comes to mind is making all of the packet classes can inherit from some base packet class. Then you can make the event use that base class and have the handlers only process packets of the expected type.
|
|
|
|
|
That's disappointing.
Packets is actually an enum of type-codes for each packet. Then the plug-ins parse the data (which is fed through a PacketEventArgs class) based on the type code.
It seems about the only option would be to have a giant switch statement of packets, or a manager.Register(Packets.SomePacket, MyHandler) function.
I think i'll end up going the latter route, a gigantic switch statement just doesn't appeal to me.
Thanks for your help.
|
|
|
|
|
I had assumed you had a set of classes since generics would not accept an enum value as the type parameter (since it is a constant and not a type). You could still take the approach of letting the handlers receive all events and only process the ones they care about. Something like:
void PacketProcessor(object sender, PacketEventArgs e)
{
if (e.PacketType != Packets.SomePacket) return;
}
This has the advantage of making it obvious to the later reader of the code which packet is being handled by this function, but has the disadvantage all packet handlers will get called for all packets.
|
|
|
|
|
Hello, As you may see below, I'm trying to replace the contents of two tables with eachother from a Windows form but it doesn't work. It may not be the best practice I know and waiting for your valuable comments
SqlConnection conn = new SqlConnection();
SqlDataAdapter sqlAdaptorSource;
SqlDataAdapter sqlAdaptorTarget;
SqlCommandBuilder sqlCommandSource;
SqlCommandBuilder sqlCommandTarget;
DataTable dtSource = new DataTable();
DataTable dtTarget = new DataTable();
DataTable dtBackup = new DataTable();
public void changeTables()
{
conn.ConnectionString = @"Data Source=" + System.Environment.MachineName + @"\SQLEXPRESS;Initial Catalog=Kafe;Integrated Security=SSPI;";
conn.Open();
sqlAdaptorSource = new SqlDataAdapter("Select * From Table1", conn);
sqlAdaptorTarget = new SqlDataAdapter("Select * From Table2", conn);
sqlCommandSource = new SqlCommandBuilder(sqlAdaptorSource);
sqlCommandTarget = new SqlCommandBuilder(sqlAdaptorTarget);
sqlAdaptorSource.Fill(dtSource);
sqlAdaptorTarget.Fill(dtTarget);
dtBackup = dtTarget;
dtTarget = dtSource;
sqlAdaptorTarget.Update(dtTarget);
dtSource = dtTarget;
sqlAdaptorSource.Update(dtSource);
dtSource.Clear();
dtTarget.Clear();
dtBackup.Clear();
dtSource.Dispose();
dtTarget.Dispose();
dtBackup.Dispose();
conn.Close();
conn.Dispose();
}
|
|
|
|
|
teknolog123 wrote: it doesn't work
does not qualify as an accurate symptom description.
Are you aware a DataTable has a TableName property? and you haven't changed a thing inside such DataTables?
so all the data stays with the table name, no matter in what order you perform your Update()s.
|
|
|
|
|
thanks for your comment, would please show me a way of replacing the tables' contents? And how TableName property can help me?
|
|
|
|
|
Hy,
There's some wierd stuff in here:
dtBackup = dtTarget;
dtTarget = dtSource;
sqlAdaptorTarget.Update(dtTarget);
dtSource = dtTarget;
sqlAdaptorSource.Update(dtSource);
First you make the dtBackup refernce the dtTarget.
Then you the dtTarget reference the dtSource => the backup also points to dtTarget wich in
turn points to source.
Then you update the dtTarget, but the target points to source => so you update the source.
All of them point to the same thing
Remeber objects are passed default by reference.
What you want to do works fine for value types such as ints:
tmp = second;
second = first;
first = tmp;
|
|
|
|
|
thanks, would please show me a way of replacing the tables' contents?
|
|
|
|
|
use the Clone() method as in:
DataTable bckup = dt.Clone();
|
|
|
|
|
|
Hi everyone!
I have recently created a program when you click a button then a running (scrolling) string is appeared on the TextBox component....this line is "running" from right to left (like in Winamp) ...I used a timer object to alter string by replacing the leftmost character to the end of a string ...so it looked like it was moving ....but I don't understand:
every time i was using this code in Timer.Elapsed handler:
str = str.Substring(1, str.Length - 1) + str.Substring(1, 0);
txtMessage.Text = str;
so everytime the timer fires an event, a new string object is created (cause string are immutable in C#)
but in the System Process window it ate no memory at all!!!!
Does GarbageCollector work so fast?
|
|
|
|
|
Just how fast was this timer? Or just how slow was your PC?
Seriously though, .NET applications get an allocation of memory when they start, unless you exceed that there would be no need to allocate more. The System Performanec window won't help you at all! For more details, see here[^] and here[^].You should never use standby on an elephant. It always crashes when you lift the ears. - Mark Wallace
C/C++ (I dont see a huge difference between them, and the 'benefits' of C++ are questionable, who needs inheritance when you have copy and paste) - fat_boy
|
|
|
|
|
When a new object is to be created and there is insufficient free memory inside your .NET app, the GC will try and free some, and when that were to fail, it would ask Windows for more memory. Every time the GC runs, it blocks your app, so it isn't really correct it is fast, all it does is steal the CPU to do its job. Which in most situations is quite all right.
What I tend to do in larger applications is have a Windows.Forms.Timer periodically send some statistical information to a Label, one useful item is Environment.WorkingSet (which I reduce by 1024*1024 to get it in megabytes). That often tells me how well the GC is doing, and gives me some clue when I am keeping on to too many objects (by accident).
|
|
|
|
|
Don't use Task Manager to see how much memory your app is using. What you actually seeing is how much memory the .NET CLR has reserved for your application, even if your app isn't using it all. Use Performance Monitor instead and the .NET Memory counters for a more accurate representation of your applications memory usage.
BTW: It's completely unneccessary to be creating and deleting so many strings. A better implementation would be to use an image of the string, then just move the image over 1 or pixels at a time for the scrolling effect.
|
|
|
|
|
Nick Reshetinsky wrote: Does GarbageCollector work so fast?
Yes, the garbage collector can work very fast for some types of memory (I am guessing for strings). Though some objects don't get garbage collected very fast (large objects, those with finalizers, and so on).
Strings are a special case, as they sometimes get interned (or, stored in a special way so it can be referenced by multiple objects). However, that is not typically done for runtime generated strings, such as those generated in the code you've posted above. So, they are not getting interned and the garbage collector is free to collect them.
Also keep in mind that you may only be generating a few unique strings (Maybe a few hundred), as I your scroller rotates (I imagine). So, even if your strings were interned, you still would not be eating up gobs of memory. And I'm sure your scroller isn't running too fast, which means that you'll not be consuming very much memory... even if the garbage collector ran every minute, you might not see a noticeable jump in memory in that timeframe.
|
|
|
|
|
strings get interned only if:
- they are literals, so the compiler interns them;
- the app explicitly calls string.Intern()
when they don't get interned, they don't get compared against each other either, so "you may only be generating a few unique strings" isn't really relevant; his code is generating millions of strings. And they get collected.
This[^] describes a string interning experiment showing it pays off when lots of compares are needed in a set with high multiplicity.
|
|
|
|
|
I know. You'll note that I said they don't typically get interned for runtime generated strings and that, if they (hypothetically) were (such as by using string.Intern), there were only a few unique strings so they would (hypothetically) not cause much of a memory footprint. By "unique", I meant the data would be unique, not the instances of that data ("A" and "A" are not unique, but they are two different instances). Was just pointing out some things the OP might want to think about (since the OP seems more interested in learning rather than solving a specific problem, as there isn't really a problem presented by the OP).
|
|
|
|
|
OK, we agree on the absence of a problem then. Time to move on.
|
|
|
|
|
I think, first, we should agree that we both agree there is no problem. And then we should agree that we both agree that we both agree there is no problem.
|
|
|
|
|
I can't argue with that.
|
|
|
|
|
Hello, i'm trying to write a quick mock up system so my mother knows the colours of pictures when she cross stitches. I would like to import a picture overlay a grid i think it's 1mm boxes then be able to pick up the pixel or rgb colour. I've written the code to convert the colours to pattern chart colours but i was wondering if it was possible to overlay a grid then tell the colour of each square so i can easily convert it. I heard c# has a grid function as standard however i'm struggle to find it or use it
|
|
|
|
|
I'm unaware of any grid function, other than some Grid Controls which show tabular data.
showing a grid on top of an image can be accomplished easily with some code along these lines, using a Panel and assuming the image fits within the screen bounds:
public void myPanel_Paint(object sender, PaintEventArgs e) {
Graphics g=e.Graphics;
g.DrawImage(myImage, 0, 0);
int w=myImage.Width;
int h=myImage.Height;
int GRIDSTEP=20;
for (int x=0; x<w; x+=GRIDSTEP) g.DrawLine(Pens.Yellow, x, 0, x, h);
for (int y=0; y<h; y+=GRIDSTEP) g.DrawLine(Pens.Yellow, 0, y, w, y);
}
Alternatively, you could use an overload of DrawImage to get the image scaled if necessary;
note that I didn't use a PictureBox as I don't like them much.
|
|
|
|
|
hey thats the kinda thing i was looking for, quick question been a long time since i used forms, but when inserting the image is there a way of saying that the image = my image. I was under the impression it was something like backgroundimage = myimage(x,y,z). Also is there a way of picking the colour out to rgb?
|
|
|
|