I added 2 button event handlers to stop the thread loop
First one will end the loop by using a variable to stop it
Second one will abort the thread directly
U dont need to use the thread.join method ... Lets say u start the thread using a button in a form ... no need for the join, cause the application will keep running.
In case u start the thread in your void Main() ... u should use it. cause else after u start the thread, the application will end (end of void main reached) and your thread will be aborted
[code]
using
System;
using
System.Collections.Generic;
using
System.Text;
// Add the threading namespace
using
System.Threading;
namespace
ComboBoxValues
{
public class ThreadSample
{
// Thread handle
Thread myThread = null;
// Exit flag
private bool m_exit = false;
public void StartThread()
{
// Reset the exit flag
m_exit =
false;
// Create the thread
myThread =
new Thread(new ThreadStart(myThread));
// Start the thread
myThread.Start();
// Wait for the thread to end
myThread.Join();
}
public void MyThread()
{
// Loop until the exit flag is set to trough
while (!m_exit)
{
// Continous loop code
// Save some cpu usage
Thread.Sleep(10);
}
}
public void Button1_Click(object sender, EventArgs e)
{
// Set the exit flag to true
// Code will process till end of the loop, then will abort
// Thread will be ended successful
m_exit =
true;
}
public void Button2_Click(object sender, EventArgs e)
{
// Abort the thread
// Code will be aborted even when not end of loop is reached
// Thread will be ended non successful (ThreadAbortException)
there is another option, and it is to call Application.DoEvents (),
Thanks Mario, that works fine - but I find I need to double click on the button - a single click does nothing - is this normal or have I upset some other parameter
best practices for continous code is using threads like most people say in here :)
Not so smart to use a continous loop inside a program. Altho there are few ways to make continous code.
1. Threads <<< U should really try it, its easy and fun to work with.
2. Maybe try adding a event handler to Application.Idle event
In case u know a little c++ u will know there is allready a mainloop in each application, checking for messages (like the window paint message, button click messages)
.NET translates this all for u in events and stuff ... but still, when there is no message received the application is idle, so u can attach an event handler to the application.idle event ;)
This way your code will been executed continously ... but event like button click events will be processed before your code is called.
best practices for continous code is using threads
1. Threads <<< U should really try it, its easy and fun to work with.
2. Maybe try adding a event handler to Application.Idle event
Thanks for the reply. This is my first few days of programming in Windows (Visual C#) - I have written complex programmes in C and assembler but always at DOS level. Can you give me a complete example using a thread to operate a continuous loop started with a button click and using a different button to stop the loop.
Thanks for you reply Mario - I have typed in the exact example as you have given it except the sleep statement which I have typed as follows:-
System.Threading.Thread.Sleep(10);
I need two clicks of button2 to stop the loop. It can be two quick clicks or two clicks a few seconds apart but it definitely need two clicks. I am running C# Express. Are you sure it should operate with one click
Create a global thread variable. And in your void, create a threadstart that address of the procedures / functions. Add this threadstart to this thread variable and do a start.
In other button, assigned an abort or interrupt action to stop the thread.
Colin, you are totally right: the example I gave you does require two clicks... weird.
My original code was written for two toolstrip buttons, and those will have no problem. The buttons instead will require the two clicks you were talking about. The reason seems to be that the button control keeps the mouse captured through all the execution of the event. The extra click is needed to "convince" the first button to release the capture and is therefore lost as a click.
As I mentioned before, not all controls behave this way.
You can release the capture from Button1, changing the code to:
Well, a single click must work. If you have to click multiple times to get your button behave, then you might not be calling DoEvents often enough. Try to split the lengthy process in parts and call DoEvents after each part.
Colin, it is usually not a good idea to have an event executing for a long time, as while you are serving an event, the other events get blocked. This amounts to freeze the user interface.
If you plan to have a lengthy task running in response to a button click, you should probably use a Thread, or the ThreadPool. It's fairly easy to use, and it's well worth the little time it takes to set them up, as the code becomes cleaner and easier to manage.
Anyway, there is another option, and it is to call Application.DoEvents (), that will allow other events to be raised and served. The obvious drawback is that you might reenter the same event, and this might lead to unexpected results. What follows is a silly example of how you may go using DoEvents ():
private bool stop = false; private void Button1_Click (...) { stop = false; for (int i = 0; (! stop) && (i < 1000); i++) { // do something time consuming here... for instance: Thread.Sleep (100); Application.DoEvents (); } if (stop) MessageBox.Show ("Stopped"); else MessageBox.Show ("Done"); }
How do I test a button when running an event?
JohnRM2
Here some sample code for using threads.
I added 2 button event handlers to stop the thread loop
First one will end the loop by using a variable to stop it
Second one will abort the thread directly
U dont need to use the thread.join method ... Lets say u start the thread using a button in a form ... no need for the join, cause the application will keep running.
In case u start the thread in your void Main() ... u should use it. cause else after u start the thread, the application will end (end of void main reached) and your thread will be aborted
[code]
using
System;using
System.Collections.Generic;using
System.Text;// Add the threading namespace
using
System.Threading;namespace
ComboBoxValues{
public class ThreadSample{
// Thread handle Thread myThread = null; // Exit flag private bool m_exit = false; public void StartThread(){
// Reset the exit flagm_exit =
false; // Create the threadmyThread =
new Thread(new ThreadStart(myThread)); // Start the threadmyThread.Start();
// Wait for the thread to endmyThread.Join();
}
public void MyThread(){
// Loop until the exit flag is set to trough while (!m_exit){
// Continous loop code // Save some cpu usage Thread.Sleep(10);}
}
public void Button1_Click(object sender, EventArgs e){
// Set the exit flag to true // Code will process till end of the loop, then will abort // Thread will be ended successfulm_exit =
true;}
public void Button2_Click(object sender, EventArgs e){
// Abort the thread // Code will be aborted even when not end of loop is reached // Thread will be ended non successful (ThreadAbortException)myThread.Abort();
}
}
}
[/code]
Ivo Manolov -- MSFT
Thanks Mario, that works fine - but I find I need to double click on the button - a single click does nothing - is this normal or have I upset some other parameter
Andrea43086
best practices for continous code is using threads like most people say in here :)
Not so smart to use a continous loop inside a program. Altho there are few ways to make continous code.
1. Threads <<< U should really try it, its easy and fun to work with.
2. Maybe try adding a event handler to Application.Idle event
In case u know a little c++ u will know there is allready a mainloop in each application, checking for messages (like the window paint message, button click messages)
.NET translates this all for u in events and stuff ... but still, when there is no message received the application is idle, so u can attach an event handler to the application.idle event ;)
This way your code will been executed continously ... but event like button click events will be processed before your code is called.
B&#249;i Duy Hi&#7871;u
Mario.......That is now a complete solution - Thank you very much.
stanfordholden
Thanks for the reply. This is my first few days of programming in Windows (Visual C#) - I have written complex programmes in C and assembler but always at DOS level. Can you give me a complete example using a thread to operate a continuous loop started with a button click and using a different button to stop the loop.
Thanks.
janekw
Thanks for you reply Mario - I have typed in the exact example as you have given it except the sleep statement which I have typed as follows:-
System.Threading.Thread.Sleep(10);
I need two clicks of button2 to stop the loop. It can be two quick clicks or two clicks a few seconds apart but it definitely need two clicks. I am running C# Express. Are you sure it should operate with one click
chaitea
The other way I would suggest is using Threading.
Create a global thread variable.
And in your void, create a threadstart that address of the procedures / functions.
Add this threadstart to this thread variable and do a start.
In other button, assigned an abort or interrupt action to stop the thread.
Yashraj
Colin,
you are totally right: the example I gave you does require two clicks... weird.
My original code was written for two toolstrip buttons, and those will have no problem. The buttons instead will require the two clicks you were talking about. The reason seems to be that the button control keeps the mouse captured through all the execution of the event. The extra click is needed to "convince" the first button to release the capture and is therefore lost as a click.
As I mentioned before, not all controls behave this way.
You can release the capture from Button1, changing the code to:
private void Button1_Click (...) {
stop = false;
Button1.Capture = false;
for (...
Moving the focus away would also work, but it would be inconsistent with the standard Windows behaviour.
Hope this helps
--mc
fjcardoso
Well, a single click must work. If you have to click multiple times to get your button behave, then you might not be calling DoEvents often enough. Try to split the lengthy process in parts and call DoEvents after each part.
HTH
--mc
warthog72
Colin,
it is usually not a good idea to have an event executing for a long time, as while you are serving an event, the other events get blocked. This amounts to freeze the user interface.
If you plan to have a lengthy task running in response to a button click, you should probably use a Thread, or the ThreadPool. It's fairly easy to use, and it's well worth the little time it takes to set them up, as the code becomes cleaner and easier to manage.
Anyway, there is another option, and it is to call Application.DoEvents (), that will allow other events to be raised and served. The obvious drawback is that you might reenter the same event, and this might lead to unexpected results. What follows is a silly example of how you may go using DoEvents ():
private bool stop = false;
private void Button1_Click (...) {
stop = false;
for (int i = 0; (! stop) && (i < 1000); i++) {
// do something time consuming here... for instance:
Thread.Sleep (100);
Application.DoEvents ();
}
if (stop)
MessageBox.Show ("Stopped");
else
MessageBox.Show ("Done");
}
private void Button2_Click (...) {
stop = true;
}
HTH
--mc