How to execute method n-times in a second?
-
Hi, I have WindowsForms application where I should execute method n-times in a second. The method should be executed inside of its own separate thread. I use thread pool for that purpose. UI contains text box where I enter the number of times of execution and button, which I click to start processing. I've tried to use System.Windows.Forms.Timer but it works for smaller number of executions (~ up to 100). It works means for example 50 calls can be done in 1 second. When the number of calls is growing they can't be executed in 1 second. They need more and more time. The code looks as follows:
private int count = 0; private int tps; public Form1() { InitializeComponent(); ThreadPool.SetMaxThreads(500, 500); } private void button1\_Click(object sender, EventArgs e) { listBox1.Items.Clear(); timer1.Enabled = true; tps = Int32.Parse(textBox1.Text); timer1.Interval = 1000 / tps; timer1.Start(); label1.Text = "Start time: " + DateTime.Now.ToString("hh:mm:ss.fff"); label2.Text = "End time: "; } private void timer1\_Tick(object sender, EventArgs e) { ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork)); } private void DoWork(object stateInfo) { count++; listBox1.Items.Add(count); if (count == tps) { count = 0; timer1.Stop(); label2.Text = label2.Text + " " + DateTime.Now.ToString("hh:mm:ss.fff"); timer1.Enabled = false; } label3.Text = listBox1.Items.Count.ToString(); }
Do you have an idea how I can resolve this issue? Thank you in advance. Regards, Goran
-
Hi, I have WindowsForms application where I should execute method n-times in a second. The method should be executed inside of its own separate thread. I use thread pool for that purpose. UI contains text box where I enter the number of times of execution and button, which I click to start processing. I've tried to use System.Windows.Forms.Timer but it works for smaller number of executions (~ up to 100). It works means for example 50 calls can be done in 1 second. When the number of calls is growing they can't be executed in 1 second. They need more and more time. The code looks as follows:
private int count = 0; private int tps; public Form1() { InitializeComponent(); ThreadPool.SetMaxThreads(500, 500); } private void button1\_Click(object sender, EventArgs e) { listBox1.Items.Clear(); timer1.Enabled = true; tps = Int32.Parse(textBox1.Text); timer1.Interval = 1000 / tps; timer1.Start(); label1.Text = "Start time: " + DateTime.Now.ToString("hh:mm:ss.fff"); label2.Text = "End time: "; } private void timer1\_Tick(object sender, EventArgs e) { ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork)); } private void DoWork(object stateInfo) { count++; listBox1.Items.Add(count); if (count == tps) { count = 0; timer1.Stop(); label2.Text = label2.Text + " " + DateTime.Now.ToString("hh:mm:ss.fff"); timer1.Enabled = false; } label3.Text = listBox1.Items.Count.ToString(); }
Do you have an idea how I can resolve this issue? Thank you in advance. Regards, Goran
-
Hi, I have WindowsForms application where I should execute method n-times in a second. The method should be executed inside of its own separate thread. I use thread pool for that purpose. UI contains text box where I enter the number of times of execution and button, which I click to start processing. I've tried to use System.Windows.Forms.Timer but it works for smaller number of executions (~ up to 100). It works means for example 50 calls can be done in 1 second. When the number of calls is growing they can't be executed in 1 second. They need more and more time. The code looks as follows:
private int count = 0; private int tps; public Form1() { InitializeComponent(); ThreadPool.SetMaxThreads(500, 500); } private void button1\_Click(object sender, EventArgs e) { listBox1.Items.Clear(); timer1.Enabled = true; tps = Int32.Parse(textBox1.Text); timer1.Interval = 1000 / tps; timer1.Start(); label1.Text = "Start time: " + DateTime.Now.ToString("hh:mm:ss.fff"); label2.Text = "End time: "; } private void timer1\_Tick(object sender, EventArgs e) { ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork)); } private void DoWork(object stateInfo) { count++; listBox1.Items.Add(count); if (count == tps) { count = 0; timer1.Stop(); label2.Text = label2.Text + " " + DateTime.Now.ToString("hh:mm:ss.fff"); timer1.Enabled = false; } label3.Text = listBox1.Items.Count.ToString(); }
Do you have an idea how I can resolve this issue? Thank you in advance. Regards, Goran
The bad news is that you can't resolve this issue. If you think about it for a little bit, you'll see why. Here's a hint - you need to execute a task several number of times a second and those tasks take a finite amount of time; creating the threads (or switching to them in a threadpool) also takes a period of time - even if you are running on a multi-core machine, there are only a set number of tasks that can be spawned and run in that period of time. By the way, you have a marshalling issue in your code (you may be suppressing it, but it still takes time). Basically, you are interacting with a UI component from a none-UI thread. WinForms is STA, so you should be marshalling the calls back to the UI thread.
Forgive your enemies - it messes with their heads
My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility
-
Try System.Timers.Timer[^] which is more accurate than its forms counterpart.
"Don't confuse experts with facts" - Eric_V
Thanks for your answer. I've tried to use System.Timers.Timer and the results a bit better. But, there's one thing I've noticed. Sometimes, the number of items I've added to listbox is greater than number I've entered to text box. For example, when I enter 11 to text box, the number of items in list box is 12. The order is as follows: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1. I don't understand why 1 again?
-
The bad news is that you can't resolve this issue. If you think about it for a little bit, you'll see why. Here's a hint - you need to execute a task several number of times a second and those tasks take a finite amount of time; creating the threads (or switching to them in a threadpool) also takes a period of time - even if you are running on a multi-core machine, there are only a set number of tasks that can be spawned and run in that period of time. By the way, you have a marshalling issue in your code (you may be suppressing it, but it still takes time). Basically, you are interacting with a UI component from a none-UI thread. WinForms is STA, so you should be marshalling the calls back to the UI thread.
Forgive your enemies - it messes with their heads
My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility
Thanks for the answer. Yes. I supposed this couldn't be resolved to be absolutely accurate. But what to do? I need to write the application that should load test WCF RIA service and the results should be confidential.
-
Thanks for the answer. Yes. I supposed this couldn't be resolved to be absolutely accurate. But what to do? I need to write the application that should load test WCF RIA service and the results should be confidential.
If you are load testing an application, you need to take a different approach. You should be attempting to target it from multiple machines.
Forgive your enemies - it messes with their heads
My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility
-
Hi, I have WindowsForms application where I should execute method n-times in a second. The method should be executed inside of its own separate thread. I use thread pool for that purpose. UI contains text box where I enter the number of times of execution and button, which I click to start processing. I've tried to use System.Windows.Forms.Timer but it works for smaller number of executions (~ up to 100). It works means for example 50 calls can be done in 1 second. When the number of calls is growing they can't be executed in 1 second. They need more and more time. The code looks as follows:
private int count = 0; private int tps; public Form1() { InitializeComponent(); ThreadPool.SetMaxThreads(500, 500); } private void button1\_Click(object sender, EventArgs e) { listBox1.Items.Clear(); timer1.Enabled = true; tps = Int32.Parse(textBox1.Text); timer1.Interval = 1000 / tps; timer1.Start(); label1.Text = "Start time: " + DateTime.Now.ToString("hh:mm:ss.fff"); label2.Text = "End time: "; } private void timer1\_Tick(object sender, EventArgs e) { ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork)); } private void DoWork(object stateInfo) { count++; listBox1.Items.Add(count); if (count == tps) { count = 0; timer1.Stop(); label2.Text = label2.Text + " " + DateTime.Now.ToString("hh:mm:ss.fff"); timer1.Enabled = false; } label3.Text = listBox1.Items.Count.ToString(); }
Do you have an idea how I can resolve this issue? Thank you in advance. Regards, Goran
Some comments: 1. this article may enlighten you on some timer characteristics: Timer surprises, and how to avoid them[^] 2. this one could help you in solving cross-thread problems: http://www.perceler.com/articles1.php?art=crossthreads1[^] 3. ThreadPools have their own algorithm for launching and creating threads; e.g. launching ten jobs at pretty much the same time would not necessarily cause ten threads to be used, and that is why it's method is called
QueueUserWorkItem
, rather thanExecuteNow
. Last time I checked, the ThreadPool, when sufficient work has been queued, would launch new threads at a pace of 2 per second. 4. Load testing a component may not be handled best with equidistant requests; I would consider using a fixed number of real threads (not pooled ones), and give each the job to wait a random time, then issue a request, in a loop-forever style. That way you can simulate an average load of your choice with arbitrary phase between the requests. Furthermore I agree with Pete, when he says having more machines to realistically simulate load would be better. :)Luc Pattyn [My Articles] Nil Volentibus Arduum