|
What you are doing here is potentially a bit risky.
What happens when you call ThreadPool.QueueUserWorkItem is that the method is queued on the thread pool and the main thread continues immediately. Then, when a thread in the pool becomes free, it does the requested work.
By default there are no threads in the pool, and every time work is requested one is created, up until a max (which I think is about 25 by default).
What you are doing is adding 10000 requests to the pool very quickly. So 25 threads will be created. You are then left with 9975 jobs left in the thread pool queue. These will wait until the first 25 begin to finish, then the threads will start processing them.
There are three things to be aware of with this approch.
1) When your reach the objTimer.Stop(); line, your thread pool is still processing the tasks. If you killed your app at this point without letting the thread pool finish, not all the log entries would be written.
2) You cannot guarantee that the tasks will be performed in the order you added them to the thread pool. If the order of the log entries is important, this solution is no good. (Although it's a queue, all this means is that the jobs get started in the correct order, it's possible a job could get pre-empted and switched out before it's written the log so a different log entry could get written first)
3) You should note that the logging still takes the same amount of time, just it's being done away from the main thread so you aren't timing it. This means if your main thread is adding log requests to the thread pool faster than the thread pool can process them you risk the queue getting longer and longer and longer and the thread pool not being able to keep up. Eventually, it will get so far behind that the logs actually get processes ages after they were originally added, and potentially even fill up memory if the queue gets too large. (Also, the same amount of CPU time is taken up. If it's got multiple CPUs the work may be done on a different CPU, but if the system is already maxed out all it's CPUs from your main app, this isn't going to improve anything, all that will happen is that the main app threads will have to run slower to allow the thread pool to work)
Ok. So that's the bad news. However, I have an idea that might help you.
Assuming you are happy with processing on the background thread as means for improving 'performance', you could use a producer/consumer thread queue.
The idea is that you have a queue of tasks. You can add new tasks to the end of the queue. A single thread processes tasks from the front of the queue. It has to be just 1 thread to prevent the risk of the tasks order getting swapped. (Similar to the idea of using the thread pool, but restricting it to one thread). Then, you also add a queue size restriction. When the queue reaches it's maximum size, when an attempt is made to add to it, it blocks until the queue reduces. You could set your queue restriction size to a few thousand, so your app would run, adding tasks to the queue really quickly, but if the queue ever got full, it would slow up to allow the queue to be cleared a bit.
This will only really help if your app makes a lot of log requests in a short period of time, then stops for a bit. This way the log requests won't slow it up during the busy period, and they can be processed in the background while the main app idles.
(This is fairly tricky to implement correctly, so do some research and check out existing produce/consumer queue. There are plenty of examples on google. The tricky bit is making sure the queue is locked correctly during enqueue and dequeue operations, and that the consumer thread waits correctly when the queue is empty)
[Edit: Good luck ]
Simon
|
|
|
|
|
Dear Simon,
You have answered my question on log4net very clearly. Thanks for your detailed explanation.
I have reached the same conclusions you mentioned. Using threads is always risky and complicated. Personally I always try to avoid using multi-threaded solutions as much as possible!
Best Regards,
F. Badili
|
|
|
|
|
hi..
I'm using Splitcontainer and drawing a sine wave using GDI+ object on the panel2 of the Splitcontainer, now i need to capture the sinewave in panel2 and save it to bit map.. so pls help me how to capture and save the waveform (panel2 contents) into the bitmap.
if possible, pls provide me some reference links..
thanks in advance
vinay
|
|
|
|
|
You can't capture what you have drawn, as there is no guarantee at all that it's still on the screen, or even that it was actually drawn on the screen in the first place.
Create a Bitmap with the same size of the control, use Graphics.FromImage to get a Graphics object to draw on the bitmap, and use the same code that you are using to draw on the panel to draw on the Bitmap.
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
hi..
PointF[] pfTempData = GetCalculatedPoints(intIndex);
panel2Graphics.DrawCurve(new Pen(Color.Black, 0F), pfTempData);
im using the above code to draw a sine wave, but how to draw the same onto bitmap.
i tried like this
Panel2Graphics.DrawImage(bmpExport, pfTempData);
but gives as error like
{System.ArgumentException: Destination points must be an array with a length of 3 or 4. A length of 3 defines a parallelogram with the upper-left, upper-right, and lower-left corners. A length of 4 defines a quadrilateral with the fourth element of the array specifying the lower-right coordinate.<br />
at System.Drawing.Graphics.DrawImage(Image image, PointF[] destPoints)<br />
at GDIWaveformViewer2.PlotPanel.DrawGraph(Graphics gPanel2Graphics) in D:\Documents and Settings\vinayakumark\Desktop\Viewer-18july\Viewer\PlotPanel.cs:line 327}
please suggest me what to do..?
|
|
|
|
|
You are trying to draw the bitmap on the panel, which is pretty much the opposite of what you want to do... You get that exception because you are using the wave coordinates as the bounds for where the bitmap is drawn on the panel.
Use the Graphics.FromImage method as I suggested, so that you get a Graphics object that you can use to draw on the bitmap. Then you just draw the wave on the bitmap the same way that you draw it on the screen.
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
ok i got it, i tried in the way how u sugessted me..
now im having two bitmap object's, one containing scale & other one containing waveform. how to combine these 2 bitmap objects to plot it as one bitmap image on the screen..
|
|
|
|
|
i want to get the x,y cordination of the clicked point on the desktop by the user(not on the form)
actually i want to move the form to the where the user clicked,
|
|
|
|
|
|
Hi all,
I have a windows form that has on it 40ish buttons with images, 8 image box's, a couple of labels and that's it. However when ever it comes to redrawing it it takes forever! Any idea on what I can do to stream line it?
I'm using .net 2.0 could it be sped up by going to 3.0 or 3.5 and using WPF?
It's going to be running on a mini machine with 1GB Ram and 499Mhz processor.
Thanks For your help
Michael
|
|
|
|
|
I suspect you are doing something wrong. I've just setup a form with 50 buttons, all with different images, 10 pictureboxs all with different images and 10 labels and it runs perfectly smoothly.
How are you loading your images?
Check that you definitely aren't reloading them for every refresh.
Check that your images aren't massive and being scaled for the buttons.
That is a very low spec system though, your barely above the minimum cpu for windows XP. Even our industrial SFF pc's that we use out on the shop floor have specs way above that.
WPF/3.5 won't improve anything.
Simon
|
|
|
|
|
hopingToCode wrote: I have a windows form that has on it 40ish buttons with images, 8 image box's, a couple of labels and that's it.
First, this sounds like a UI design nightmare in progress.
hopingToCode wrote: It's going to be running on a mini machine with 1GB Ram and 499Mhz processor.
This is barely enough to run Windows XP. There are two ways to speed up drawing that form. The first is to upgrade the machine to something built in the last 4 years.
The second way is to reduce the number of controls on the form, probably by reorganizing your user interface.
Moving to .NET 3.5 and WPF will only make things worse because you'll have higher minimum system requirements than the machine you now have.
|
|
|
|
|
Hi folks,
does anybody have an idea how to implement a shared server document ?
Let me explain you my needs ...
I shall implement the ability to simultaneously edit and read a word - document by multiple users ?
is this possible ? and if so, do you folks have any snippets that could help me do my job ?
thx a lot
|
|
|
|
|
You can do this kind of thing with a share point server & word 2003/2007 I believe.
This would not be easy to write yourself. You would have to write a server, and transmit all changes made by each user to the server. The server would have to merge the changes, resolve any conflicts that occurred because of users making edits at the same time, and retransmit the results back out to each client.
Simon
|
|
|
|
|
Use MOSS 2007
Cheers!!
Brij
|
|
|
|
|
Hi all,
I have the following anonymous LINQ statement, how can I select the distinct file name, because foreach statement does not perform the desired action cause of the FullPath that differs for each file.
var distinctFiles = from f in Directory.GetFiles(@"C:\My Files").AsEnumerable()
select new
{
FileName = f.Split(new Char[] { '_' })[1],
FullPath = f
};
foreach (var file in distinctFiles.Distinct())
{
....
}
Many thanks in advance
Kind reagrds,
The only programmers that are better those C# programmers are those who code in 1's and 0's |
Programm3r
My Blog: ^_^
|
|
|
|
|
You can't select the distinct file name, as you are not getting only the file name. First you have to decide how to determine which full path you want to keep for each distinct file name.
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
Guffa wrote: You can't select the distinct file name, as you are not getting only the file name.
No exactly, I am using a split cause all of the files are named in a certain format, and making use of the split enables me to get hold of a certain piece of the name.
Guffa wrote: First you have to decide how to determine which full path you want to keep for each distinct file name.
I am doing this as mentioned above, but the thing is that the first part of the file name is a date and time and the second a number, now it can be that the number appears twice as the date and time differs from another file that might have been created a few seconds ago, but with the same number.
The only programmers that are better those C# programmers are those who code in 1's and 0's |
Programm3r
My Blog: ^_^
|
|
|
|
|
You can't just use distinct when there is more to what you are getting that just the part you want to be distinct.
You need to use the override of distinct that takes an equality comparer. Then in the comparer, you can provide an implementation of how to determine if the data is distinct or not.
However, you can't do this with anonymous types.
One way of doing it would be like this:
class Program
{
static void Main(string[] args)
{
String[] files = Directory.GetFiles(@"C:\My Files");
var distinctFiles = files.Distinct(new FileEqualityComparer());
foreach (var file in distinctFiles)
{
Console.WriteLine(file);
}
Console.ReadLine();
}
}
public class FileEqualityComparer : EqualityComparer<string>
{
public override bool Equals(string x, string y)
{
String FileNameX = x.Split(new Char[] { '_' })[1];
String FileNameY = y.Split(new Char[] { '_' })[1];
return FileNameX == FileNameY;
}
public override int GetHashCode(string obj)
{
String fileName = obj.Split(new Char[] { '_' })[1];
return fileName.GetHashCode();
}
}</string>
But that's not great because it will be doing the split code for every comparisom. A better way to do it would be to define a new class or struct to hold your 'file' data.
Simon
|
|
|
|
|
Many thanks for your input.
Regards
The only programmers that are better those C# programmers are those who code in 1's and 0's |
Programm3r
My Blog: ^_^
|
|
|
|
|
hello Friends,
i need simple accounting software source code in C# for learn more about accounting software projects . Please help me if possible
Thanx
|
|
|
|
|
|
From the sound of the project, I think he may already be familiar with Rent-A-Coder.
|
|
|
|
|
Dave Kreskowiak wrote: he may already be familiar with Rent-A-Coder
Sounds like it. Hmmm, a rent-a-coder going on to rent-a-coder to have another rent-a-coder to hire another rent-a-coder (and so on) ...
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
"Not only do you continue to babble nonsense, you can't even correctly remember the nonsense you babbled just minutes ago." - Rob Graham
|
|
|
|
|