|
You're absolutely right. Simply having two threads continuously waiting one on the other isn't necessarily better than having just one thread handle everything.
However, assuming a multi-core processor is used, a ping-pong approach (two buffers, one filled by the producer, one emptied by the consumer, and switching places based on an overall clock) could double the throughput.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Luc Pattyn wrote: (two buffers, one filled by the producer, one emptied by the consumer, and switching places based on an overall clock) could double the throughput.
I thought something like that when I read the original question. There's probably a name for the technique, although I am not aware of it. Some form of Queue-like structure that the producers add their output to with a consumer that takes the head of the queue and displays it.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
Why do programmers often confuse Halloween and Christmas?
Because 31 Oct = 25 Dec.
|
|
|
|
|
|
we've always referred to it as "ping-pong buffering" and that is also mentioned near the middle of this[^].
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
i have an assembly (dll) deployed to a remote machine. i have the visual studio project for that assembly opened in my local desktop. due to my requirements i need to debug the assembly and run through the code locally when it is loaded in the remote machine. is it possible and how? tia.
----------------------------------------------------------
Lorem ipsum dolor sit amet.
|
|
|
|
|
Have a look here.
My signature "sucks" today
|
|
|
|
|
I have a windows service in C# .net 2.0. At the moment all it is doing is being instantiated, setting up a timer and then every interval (eg 1 minute) writing to a log file. The memory usage on TaskManager goes up and up ...
I can't see any objects that I've left lying around - I've taken out pretty much everything it is meant to do ... perhaps I'm being paranoid and the garbage collector will come and clean up when it is ready? How long should I leave it? It's been a while since the last Windows Service I wrote ... any ideas?
Thanks in advance
Here are some excerpts from the code...
The LogFile is a static class with a single static method "Write"
public static class LogFile
{
public static void Write(string message)
{
string logFileName = (String)(new AppSettingsReader()).GetValue("log-file-path", typeof(String)) + "FileLoaderServiceLog.txt";
File.AppendAllText(logFileName, DateTime.Now.ToString("dd-MMM-yyyy HH:mm:ss") + " FileLoaderService:" + " " + message + Environment.NewLine);
}
The Service class itself
public partial class FileLoaderService : ServiceBase
{
private Timer serviceTimer;
public FileLoaderService()
{
InitializeComponent();
serviceTimer = new Timer();
double intervalInMinutes = (double)(new AppSettingsReader()).GetValue("timer-interval-in-minutes", typeof(double));
serviceTimer.Interval = intervalInMinutes * 60 * 1000;
serviceTimer.Elapsed += new ElapsedEventHandler(serviceTimer_Elapsed);
}
protected override void OnStart(string[] args)
{
LogFile.Write("Service Started - starting timer");
serviceTimer.Start();
}
protected void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
serviceTimer.Stop();
LogFile.Write("Checking Queue...");
serviceTimer.Start();
}
protected override void OnStop()
{
serviceTimer.Stop();
serviceTimer = null;
LogFile.Write("Service Stopped");
}
}
And Program Main ...
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new FileLoaderService() };
ServiceBase.Run(ServicesToRun);
}
}
modified on Tuesday, June 1, 2010 6:24 PM
|
|
|
|
|
In your OnStop method, you should Dispose of the timer rather than set it to null. As far as the rest goes, the garbage collector will run when it needs to. You shouldn't need to get the log filename every time, get it once and store it in a static field.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Thanks. I'll make the changes and let it run for a few hours.
|
|
|
|
|
If you want to make it easier on yourself for debugging, move the code into a separate assembly, and debug it from a console app. That's the way I develop windows services. Once I've got the core code working correctly, I then write the service assembly itself that references the core code assembly, and anything that goes wrong at that point is the fault of the service code itself.
As to your problem, I don't use the Timer objects. I prefer to set up a thread that does the timer work, and another thread that performs the actual work. This way, you can see if the worker thread is busy and if so, you can just ignore the request to write the log file (or even queue it up for processing later).
If you want to save some processing time, retrieve your settings just one time, which brings to the forefront your AppSettingsReader object. Could that be one of the the sources of your memory leak?
Lastly, if an object you're creating has a Dispose method (like the Timer objects do), call it before setting the object to null.
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
I thought about using Threads but decided it was complexity that my future replacement just didn't need.
When it comes down to it ... should the service return to a low level of memory usage after each iteration? I would say it should and casting my mind back to other services I've written they generally did - but I've been asleep since then and can't say with certainty.
I get what you're saying about the AppSettingsReader ... definitely bad form to call it everytime anyway - even if it isn't the source of the leak.
I spent an hour going through our company "data layer" yesterday - apparently the author was of the "the garbage collector will sort it out" type so nothing is ever disposed or closed or set to null. How our database server is still up I'll never know. So once I make sure my service code is all enclosed in a nice code nappy I'll have the joy of fixing that up - yay.
Thanks for taking a look for me
|
|
|
|
|
Most likely, it's that you keep instantiating the AppSettingsReader in the LogFile.Write method; you shouldn't need to to that.
Everything else looks OK to me (it's the same way I write Windows Services), but I strongly suggest a try/catch/finally in the serviceTimer_Elapsed method.
Edit: Oh, wait, don't throw away the Timer in OnStop, just leave it stopped. If you want, you can write a Dispose for the FileLoaderService that will dispose of the Timer. Otherwise, you should instantiate the Timer in OnStart.
The reason for this is if you ever do have multiple Services hosted in one process. With your current implementation, you can't stop and restart just one.
|
|
|
|
|
Thanks for your reply
I see what you mean about the AppSetttingsReader ... I had originally called it once in the constructor but changed it after some advice from a friend. We both figured that because it was a null reference it should be cleaned up ... nevertheless it is better form to only get it once - I agree.
And .. I get what you mean about the OnStop ... Thanks
|
|
|
|
|
I implemented the suggestions given and the memory still grew. In the end the only way to stop the memory growth was to take out the logging altogether! So I had a service sit there and when the timer fired go Timer.Stop then Timer.Start - doing nothing else at all.
Out of curiosity I changed the LogFile so it was no longer static and provided Open, Write & Close methods. In the constructor I grab the log file name from the config. On service start I call "Open" and on service Stop - "Close" and write to the log file at various points using Write. I don't like this idea for a multitude of reasons - but I did it just for testing purposes. I also removed any extraneous strings & DateTimes so my logFile.Write just writes the message to the file - no pretty DateTime stamp or anything.
I've also tried a couple of variations of the actual write ... one that uses File.AppendAllText, one that uses a FileStream & StreamWriter and one that uses TextWriter with StreamWriter. Making sure I close and dispose appropriately. The File.AppendAllText was what I used in my static LogFile ... it seems to be the worst offender for memory usage. I've now got TextWriter along with the Open on start and Close on Stop. That seems like a pants way of achieving what I want to do.
Now the memory consumption has slowed - but it still increases. Am I delusional in thinking that I can get this service to hover around a consistent memory usage? I left my original code (including calls to the database etc) running overnight and it got to 52Mb before I killed it. So in the hours between say 4pm yesterday afternoon and 7:00 this morning it grew from 8Mb to 50Mb. Not happy Jan
My code needs a nappy and I have no idea where to go now I'm not comfortable installing this on a server for it to run 24 hours a day until it kills the server ... not sure I'd be too popular if I did that
|
|
|
|
|
hello..
this program is based of C# and WPF
i draw Rectangle as mouse
but this program get stain of Rectangle
i want to disply without leaving any trace of Rectangle..
help me..
im sorry short english..
Screen Capture Image DownLoad
////////////////source///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Drawing;
namespace rectTest
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
System.Drawing.Rectangle myRec;
System.Windows.Point firstPoint;
bool flg = false;
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
flg = true;
firstPoint = e.GetPosition(mainwin);
myRec = new System.Drawing.Rectangle((int)firstPoint.X, (int)firstPoint.Y, 0, 0);
}
private void mainwin_MouseMove(object sender, MouseEventArgs e)
{
if (flg == true)
{
System.Windows.Point currentPoint;
currentPoint = e.GetPosition(mainwin);
double width = currentPoint.X - firstPoint.X;
double height = currentPoint.Y - firstPoint.Y;
if (width > 0 && height > 0)
{
Graphics g = Graphics.FromHwnd(new System.Windows.Interop.WindowInteropHelper(this).Handle);
System.Drawing.Pen myPen = new System.Drawing.Pen(System.Drawing.Color.Red, 5);
g.DrawRectangle(myPen, myRec);
myRec.Width = (int)width;
myRec.Height = (int)height;
InvalidateVisual();
}
}
}
private void mainwin_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
flg = false;
}
}
}
modified on Tuesday, June 1, 2010 3:37 AM
|
|
|
|
|
How about erasing the old rectangle before drawing a new one?
System.Drawing.Pen myPen = new System.Drawing.Pen(System.Drawing.Color.Red, 5);
System.Drawing.Pen whitePen = new System.Drawing.Pen(System.Drawing.Color.White, 5);
g.DrawRectangle(whitePen, myRec);
myRec.Width = (int)width;
myRec.Height = (int)height;
g.DrawRectangle(myPen, myRec);
InvalidateVisual();
I have no smart signature yet...
|
|
|
|
|
if exist background image, don't this mothod
this mothod is fill the white color...
are you other mothod ??....
|
|
|
|
|
Of course there are other methods.
For example you could:
1) get the image residing in the place you drawed your first rectangle
2) put the image over the first rectangle
3) get the image residing in the place you want to draw the second rectangle
4) draw the second rectangle
5) and so on
Basicly, instead of filling with white the place where was the old rectangle, you could fill it with the old image data.
Or, if you are really lazy, you could paint the background image over the whole control in order to remove the old rectangle and maintain the background.
PS: be carefull of performance issues, drawing an image at every 20 ms it is not a good way to waste cpu time.
I have no smart signature yet...
|
|
|
|
|
Why on earth are you using GDI+ to draw your rectangle? If your application uses WPF, as you state, why not just create a WPF Rectangle object, and let WPF take care of the drawing?
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
how do working GDI+ . i don't know..
you see. mothod.. .
please..!!
|
|
|
|
|
You see this line?
Graphics g = Graphics.FromHwnd(new System.Windows.Interop.WindowInteropHelper(this).Handle); That says you're using GDI+. Here's a sample rectangle implementation that uses native WPF features instead:
private System.Windows.Shapes.Rectangle GetRectangle(double left, double top)
{
System.Windows.Shapes.Rectangle myRect = new System.Windows.Shapes.Rectangle();
myRect.Stroke = System.Windows.Media.Brushes.Black;
myRect.Fill = System.Windows.Media.Brushes.SkyBlue;
myRect.Height = 0;
myRect.Width = 0;
canvas.Children.Add(myRect);
canvas.SetLeft(myRect, left);
canvas.SetTop(myRect, top);
return myRect;
}
private System.Windows.Shapes.Rectangle myRec;
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
flg = true;
firstPoint = e.GetPosition(mainwin);
myRec = GetRectangle(firstPoint.X, firstPoint.y);
}
private void mainwin_MouseMove(object sender, MouseEventArgs e)
{
if (!flg) return;
System.Windows.Point currentPoint = e.GetPosition(mainwin);
double width = currentPoint.X - firstPoint.X;
double height = currentPoint.Y - firstPoint.Y;
if (width <= 0 || height <= 0) return;
myRec.Width = width;
myRec.Height = height;
} Please note that I've just knocked this up in Notepad, so it might require a bit of tweaking.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
I have custom control that I drag from the ToolBox onto a form.
Some of the custom control properties are set in the control's Properties Window after the control
has been dropped onto the form.
These control properties eg BindingSource and DataGridView depend on a BindingSource and DataGridView attached to the form. (Either before or after this custom control)
As these properties are referenced (but not available) in the custom control's OnPaint method, a Null Reference Exception is raised in design mode as soon as the control is placed on the form and tries to paint itself.
What would be a friendlier way to remind the developer (me) that these properties are required to be set?
Should I just do a Try/Catch and not paint the complete control or maybe paint a blank control with text
saying what other properties are required.
I am the only one probably using this control so it is no real big deal, just a nuisance and doesn't seem to be the thing to do!
Interested in how it would/should normally be handled?
|
|
|
|
|
I would not go for a full paint of a custom Control in design view if that entails complex things such as database accesses. So either check DesignMode, or (my preference) check the relevant objects to avoid null references. Which basically means: paint what you've got. Chances are you want the same behavior at run-time anyway. And if you've got nothing, then maybe paint an appropriate placeholder.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
I think that your control must be able to function even if it's not binded to data. Make it display something on it to inform you that there is no data binded (like a big red text "NO DATA BINDED" ). This sould be easy if you say that you do the painting.
I have no smart signature yet...
|
|
|
|
|
Sry for the wierd title. I made a simple program to dump data from a serial COM port. My question is how to wire the device to the serial female port so that the computer can recive the data. I am using a parallax Ping))) sensor that is already programmed to a basic stamp microcontroller. If i run the signal wire to the serial port pin 2, will I need to attach serial port pin 5 (signal ground) to the ground on the microcontroller in orderto recive a signal in the com port? The ping has an onboard A/D converter so the data is digital. P.S. If analog "data" is sent into the serial port raw, will it be converted by to computer or will bad things happen (i.e. nothing).
|
|
|
|