Waiting without Sleeping? - c#

What I'm trying to do is start a function, then change a bool to false, wait a second and turn it to true again. However I'd like to do it without the function having to wait, how do I do this?
I can only use Visual C# 2010 Express.
This is the problematic code. I am trying receive user input (right arrow for example) and move accordingly, but not allow further input while the character is moving.
x = Test.Location.X;
y = Test.Location.Y;
if (direction == "right")
{
for (int i = 0; i < 32; i++)
{
x++;
Test.Location = new Point(x, y);
Thread.Sleep(31);
}
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
int xmax = Screen.PrimaryScreen.Bounds.Width - 32;
int ymax = Screen.PrimaryScreen.Bounds.Height - 32;
if (e.KeyCode == Keys.Right && x < xmax) direction = "right";
else if (e.KeyCode == Keys.Left && x > 0) direction = "left";
else if (e.KeyCode == Keys.Up && y > 0) direction = "up";
else if (e.KeyCode == Keys.Down && y < ymax) direction = "down";
if (moveAllowed)
{
moveAllowed = false;
Movement();
}
moveAllowed = true;
}

Use Task.Delay:
Task.Delay(1000).ContinueWith((t) => Console.WriteLine("I'm done"));
or
await Task.Delay(1000);
Console.WriteLine("I'm done");
For the older frameworks you can use the following:
var timer = new System.Timers.Timer(1000);
timer.Elapsed += delegate { Console.WriteLine("I'm done"); };
timer.AutoReset = false;
timer.Start();
Example according to the description in the question:
class SimpleClass
{
public bool Flag { get; set; }
public void function()
{
Flag = false;
var timer = new System.Timers.Timer(1000);
timer.Elapsed += (src, args) => { Flag = true; Console.WriteLine("I'm done"); };
timer.AutoReset = false;
timer.Start();
}
}

I realize an answer has already been accepted, and I do like ixSci's answer where he recommends the use of a Timer object to accomplish OP's goal.
However, using System.Timers.Timer specifically introduces threading considerations. And to ensure correctness in this case, more code is required to properly synchronize the boolean flag value. Basically, anywhere where the flag is read or written, the code region would need to have a lock statement defined around it.
It would have to look something like this:
private final object flagLock = new object();
private bool moveAllowed = true;
private System.Timers.Timer timer = new System.Timers.Timer();
public Form1()
{
this.timer.Interval = 1000;
this.timer.AutoReset = false;
this.timer.Elapsed += (s, e) =>
{
// this DOES NOT run on the UI thread, so locking IS necessary to ensure correct behavior.
this.timer.Stop();
lock (this.flagLock) {
this.moveAllowed = true;
}
};
}
// The code in this event handler runs on the UI thread.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
// Locking is necessary here too.
lock (this.flagLock) {
if (this.moveAllowed)
{
this.moveAllowed = false;
Movement();
this.timer.Start(); // wait 1 second to reset this.moveAllowed to true.
}
}
}
Alternatively, to avoid having to think about threads, perhaps OP could consider using a different flavor of the Timer class. Namely: System.Windows.Forms.Timer. This way, the boolean flag will always be read/written on the UI thread, and no extra locking of any sort is required to ensure correctness.
In this case, the code would look something like this:
private bool moveAllowed = true;
private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
public Form1()
{
this.timer.Interval = 1000;
this.timer.Tick += (s, e) =>
{
// this runs on the UI thread, so no locking necessary.
this.timer.Stop(); // this call is necessary, because unlike System.Timers.Timer, there is no AutoReset property to do it automatically.
this.moveAllowed = true;
};
}
// The code in this event handler runs on the UI thread.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (this.moveAllowed)
{
this.moveAllowed = false;
Movement();
this.timer.Start(); // wait 1 second to reset this.moveAllowed to true.
}
}

Related

How to change C# Windows Forms label color for 1 sec and reset the label color? [duplicate]

I have a form that displays queue of messages and number this messages can be changed. Really I want to blink label (queue length) when the number of messages were increased to improve form usability.
Should I implement custom control and use additional thread or timer to change color of label? Has anybody implemented so functionality? What is the best solution (less resources and less performance degradation) to implement so behaviour?
SOLUTION:
Form's component with timer that can restrict number of animations per second and implement fade out effect to external control background color.
The following is blinking using async and await
private async void Blink(){
while (true){
await Task.Delay(500);
label1.BackColor = label1.BackColor == Color.Red ? Color.Green : Color.Red;
}
}
I know this is a really old post, but anyone looking for something a little more versatile than the Boolean solutions posted may get some use out of the following:
using System.Diagnostics;
using System.Threading.Tasks;
private async void SoftBlink(Control ctrl, Color c1, Color c2, short CycleTime_ms, bool BkClr)
{
var sw = new Stopwatch(); sw.Start();
short halfCycle = (short)Math.Round(CycleTime_ms * 0.5);
while (true)
{
await Task.Delay(1);
var n = sw.ElapsedMilliseconds % CycleTime_ms;
var per = (double)Math.Abs(n - halfCycle) / halfCycle;
var red = (short)Math.Round((c2.R - c1.R) * per) + c1.R;
var grn = (short)Math.Round((c2.G - c1.G) * per) + c1.G;
var blw = (short)Math.Round((c2.B - c1.B) * per) + c1.B;
var clr = Color.FromArgb(red, grn, blw);
if (BkClr) ctrl.BackColor = clr; else ctrl.ForeColor = clr;
}
}
Which you can call like such:
SoftBlink(lblWarning, Color.FromArgb(30, 30, 30), Color.Red,2000,false);
SoftBlink(lblSoftBlink, Color.FromArgb(30, 30, 30), Color.Green, 2000,true);
Timer timer = new Timer();
timer.Interval = 500;
timer.Enabled = false;
timer.Start();
if( messagesNum > oldMessagesNum)
timer.Tick += new EventHandler( timer_Tick );
else
timer.Tick -= timer_Tick;
void timer_Tick( object sender, EventArgs e )
{
if(messageLabel.BackColor == Color.Black)
messageLabel.BackColor = Color.Red;
else
messageLabel.BackColor = Color.Black;
}
Here is a pretty simple implementation that would work inside your form. You could also create a custom control with the same code and just throw the Timer.Start() into a method for that control.
Create your own UserControl for this, one that inherits from Label instead of from Control directly. Add a StartBlinking method, in which you start a Timer object whose tick event alters the style of the label (changing the BackgroundColor and ForegroundColor properties each time to create the blink effect).
You could also add a StopBlinking method to turn it off, or you could have your Timer stop itself after 5 seconds, perhaps.
You can create a custom component and events to start blinking --which I think is a good solution. The Blinking you can implement with a timer.
Can you use an animated .gif instead (perhaps as the background of the number)? it would make it look like old school web pages, but it might work.
You can use Timer class here.
Here what I have implemented.
Label color blinking on Button_click Event.
//click event on the button to change the color of the label
public void buttonColor_Click(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Interval = 500;// Timer with 500 milliseconds
timer.Enabled = false;
timer.Start();
timer.Tick += new EventHandler(timer_Tick);
}
void timer_Tick(object sender, EventArgs e)
{
//label text changes from 'Not Connected' to 'Verifying'
if (labelFirst.BackColor == Color.Red)
{
labelFirst.BackColor = Color.Green;
labelFirst.Text = "Verifying";
}
//label text changes from 'Verifying' to 'Connected'
else if (labelFirst.BackColor == Color.Green)
{
labelFirst.BackColor = Color.Green;
labelFirst.Text = "Connected";
}
//initial Condition (will execute)
else
{
labelFirst.BackColor = Color.Red;
labelFirst.Text = "Not Connected";
}
}
this is how i ended up doing it
public partial class MemberDisplay : Form
{
public string Input;
public int MASS_STOP = 1;
public MemberDisplay(string msg)
{
InitializeComponent();
State_Entry();
Input = msg;
}
public void State_Entry()
{
this.SpecialFocus.Select();
this.lbl_TimerTest.Hide();
}
private async void RunBlinkyTest(string msg)
{
while (msg == "GO" && (MASS_STOP == 0))
{
await Task.Delay(500);
lbl_TimerTest.ForeColor =
lbl_TimerTest.ForeColor == Color.Red ?
Color.Black :
Color.Red;
if (msg == "STOP" && (MASS_STOP == 1)) { return; }
}
}
private void btn_TimeTest_Click(object sender, EventArgs e)
{
if (btn_TimeTest.Text == "GO")
{
this.lbl_TimerTest.Show();
MASS_STOP = 0;
RunBlinkyTest("GO");
btn_TimeTest.Text = "STOP";
return;
}
if (btn_TimeTest.Text == "STOP")
{
MASS_STOP = 1;
RunBlinkyTest("STOP");
this.lbl_TimerTest.ForeColor = Color.Black;
this.lbl_TimerTest.Hide();
btn_TimeTest.Text = "GO";
return;
}
}
}

DispatcherTimer and Button c# conflict

I'm very new to WP8 dev and c#. I'm trying to make a loop that counts up by n on an interval. I want to press a button to increment n.
Here is my code right now:
namespace Petsounds {
public partial class MainPage : PhoneApplicationPage {
float clicks = 0;
float clickers = 0;
float clickerBuyers = 0;
float clickerCost = 5;
float clickerBuyerCost = 500;
long savedTime = DateTime.Now.Ticks / TimeSpan.TicksPerSecond;
bool buyClickerButtonFlag = false;
bool clickButtonFlag = false;
// Constructor
public MainPage() {
InitializeComponent();
//
DispatcherTimer t = new DispatcherTimer();
t.Interval = TimeSpan.FromMilliseconds(10);
t.Tick += (s, e) => startLoop();
t.Start();
}
private void clickButtonOnClick(object sender, RoutedEventArgs e) {
clickButtonFlag = true;
System.Diagnostics.Debug.WriteLine("clicked!" + clicks);
}
private void buyClickerButtonOnClick(object sender, RoutedEventArgs e) {
buyClickerButtonFlag = true;
}
private void startLoop() {
if (true) {
long nowTime = savedTime;
long timePassed = nowTime - savedTime;
//user input
if (clickButtonFlag) {
clickButtonFlag = false;
clicks++;
System.Diagnostics.Debug.WriteLine("clicked!" + clicks);
}
if (buyClickerButtonFlag) {
buyClickerButtonFlag = false;
if (clicks > clickerCost) {
clickers++;
clicks -= clickerCost;
clickerCost *= 1.6F;
}
System.Diagnostics.Debug.WriteLine("clicker bought!" + clickers);
}
//update vars
if (timePassed > TimeSpan.TicksPerSecond) {
savedTime = nowTime;
nowTime = DateTime.Now.Ticks / TimeSpan.TicksPerSecond;
clicks += clickers;
}
//update display
clickCount.Text = clicks.ToString();
buyClickerButtonCost.Text = "Cossst " + clickerCost.ToString();
}
}
}
}
My button's are inconsistent, and if I remove the thread, the buttons are responsive (but of course the counter doesn't work.)
EDIT:
I've changed
DispatcherTimer t = new DispatcherTimer();
t.Interval = TimeSpan.FromMilliseconds(10);
t.Tick += (s, e) => startLoop();
t.Start();
to
Timer myTimer = new Timer(startLoop);
myTimer.Change(1000, 10);
And now get an error:
A first chance exception of type 'System.UnauthorizedAccessException' occurred in System.Windows.ni.dll
on line
clickCount.Text = clicks.ToString();
First of all... you will quickly find that 10ms is not really 10ms... It might not even be that close... If you did 1000ms... that would be expected to be more accurate.
Also, a DispatcherTimer is going to queue up a function call to the GUI thread each interval... which means you are flooding the GUI thread with startLoop() calls. This doesn't give the thread much time to update anything else... like your buttons.
There is a different approach you might want to consider.
If your task is to increment a numeric value when a user touches a button (and have the numbers increase at a steady pace) consider using the RepeatButton.
RepeatButton: Represents a control that raises its Click event repeatedly from the time it is pressed until it is released.
XAML
<!--
Delay: The time, in milliseconds, the RepeatButton waits
when it is pressed before it starts repeating the click action.
Interval: The time, in milliseconds, between repetitions
of the click action, as soon as repeating starts.
-->
<RepeatButton Content='Buy'
Interval='50' Delay='100'
Click='RepeatButton_Click' />
Code
private float buyCounter = 0;
private void RepeatButton_Click(object sender, RoutedEventArgs e) {
buyCounter += 1;
buyClickerButtonCost.Text = buyCounter.ToString();
}
It's like #Andrew said - DispatcherTimer works on UI thread and with so small intervall you are blocking it.
If you want such a small interval you can use Timer on different Thread:
public MainPage()
{
InitializeComponent();
System.Threading.Timer myTimer = new Timer(MyTimerCallback);
myTimer.Change(1000, 10);
}
private static int value = 0;
private static void MyTimerCallback(object state)
{
value++;
}
But you must remember that you use it on different Thread - this Timer has no access to your UI elements (buttons and so on).
EDIT
You convinced me to check it:
static float clicks = 0;
static float clickers = 0;
static float clickerCost = 5;
static long savedTime = DateTime.Now.Ticks / TimeSpan.TicksPerSecond;
static bool buyClickerButtonFlag = false;
static bool clickButtonFlag = false;
public MainPage()
{
InitializeComponent();
first.Click += ShowCounter;
DispatcherTimer t = new DispatcherTimer();
t.Interval = TimeSpan.FromSeconds(5);
t.Tick += ShowCounter;
t.Start();
System.Threading.Timer myTimer = new Timer(MyTimerCallback);
myTimer.Change(10, 10);
}
private void ShowCounter(object sender, EventArgs e)
{
textBlck.Text = clicks.ToString();
}
private static void MyTimerCallback(object state)
{
clicks++; // added to check running
if (true)
{
long nowTime = savedTime;
long timePassed = nowTime - savedTime;
//user input
if (clickButtonFlag)
{
clickButtonFlag = false;
clicks++;
System.Diagnostics.Debug.WriteLine("clicked!" + clicks);
}
if (buyClickerButtonFlag)
{
buyClickerButtonFlag = false;
if (clicks > clickerCost)
{
clickers++;
clicks -= clickerCost;
clickerCost *= 1.6F;
}
System.Diagnostics.Debug.WriteLine("clicker bought!" + clickers);
}
//update vars
if (timePassed > TimeSpan.TicksPerSecond)
{
savedTime = nowTime;
nowTime = DateTime.Now.Ticks / TimeSpan.TicksPerSecond;
clicks += clickers;
}
}
}
I tested it on the device and buttons works.
On the other hand - what's the point of putting a method that waits for a flag buton click, when you can put the job easily to button click event. Let it happen when user clicked button - don't check buton state all the time.

C# Timer thread crash, BeginInvoke

I've an "animateMyWindow" class to change opened window's opacity with Timer.
namespace POCentury
{
class animateMyWindow
{
Timer _timer1 = new Timer();
Window _openedWindow = null;
public void animationTimerStart(object openedWindow)
{
if (openedWindow == null)
{
throw new Exception("Hata");
}
else
{
_openedWindow = (Window)openedWindow;
_timer1.Interval = 1 * 25;
_timer1.Elapsed += new ElapsedEventHandler(animationStart);
_timer1.AutoReset = true;
_timer1.Enabled = true;
_timer1.Start();
}
}
private void animationStart(object sender, ElapsedEventArgs e)
{
if (_openedWindow.Opacity == 1)
animationStop();
else
_openedWindow.Opacity += .1;
}
private void animationStop()
{
_timer1.Stop();
}
}
}
animationStart function can't reach my window because it is working on a different thread.
I've tried Dispatcher.BeginInvoke and can't make it work.
Can you help me with doing that?
Basically, you can't access the openedWindow inside the animationStart event because it's happening in a different thread. You need the Dispatcher to do that.
Dispatcher.BeginInvoke(new Action(() =>
{
if (_openedWindow.Opacity == 1)
animationStop();
else
_openedWindow.Opacity += .1;
}));

How to place query / other intensive logic in separate working thread BackGroundWorker

For performance i have to replace DispatcherTimer with a BackGroundWorker to handle a intensive query that runs every 5 sec by using a Threading Timer.
I no longer get any result when implementing the following code, most of the times my application shuts down as well.
public void CaculateTimeBetweenWegingen()
{
if (listWegingen.Count > 1)
msStilstand = (DateTime.Now - listWegingen[listWegingen.Count - 1]).TotalSeconds;
if(msStilstand >= minKorteStilstand)
{
stopWatch.Start();
if (msStilstand >= minGroteStilstand)
{
FillDuurStilstandRegistrationBtn();
if (zelfdeStilstand == false)
{
CreateRegistrationButton();
zelfdeStilstand = true;
}
if (msStilstand <= maxGroteStilstand){
//....
}
}
}
else //new weging
{
if (stopWatch.IsRunning == true)
{
timerStilstand.Stop();
stopWatch.Stop();
//huidige registrationBtn
if (GlobalObservableCol.regBtns.Count > 1)
{
GlobalObservableCol.regBtns[GlobalObservableCol.regBtns.Count - 1].StopWatchActive = false;
GlobalObservableCol.regBtns[GlobalObservableCol.regBtns.Count - 1].DuurStilstand =
String.Format("{0:D2}:{1:D2}:{2:D2}", stopWatch.Elapsed.Hours, stopWatch.Elapsed.Minutes, stopWatch.Elapsed.Seconds);
}
}
zelfdeStilstand = false;
}
}/*CaculateTimeBetweenWegingen*/
public void CreateRegistrationButton()
{
InitializeDispatcherTimerStilstand();
RegistrationButton btn = new RegistrationButton(GlobalObservableCol.regBtns.Count.ToString());
btn.RegistrationCount = GlobalObservableCol.regBtnCount;
btn.Title = "btnRegistration" + GlobalObservableCol.regBtnCount;
btn.BeginStilstand = btn.Time;
GlobalObservableCol.regBtns.Add(btn);
GlobalObservableCol.regBtnCount++;
btn.DuurStilstand = String.Format("{0:D2}:{1:D2}:{2:D2}", 0, 0, 0);
}
public void InitializeDispatcherTimerWeging()
{
worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(Worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();
}
void Worker_DoWork(object sender, DoWorkEventArgs e)
{
TimerCallback callback = MyTimerCallBack;
timerWegingen = new Timer(callback);
timerWegingen.Change(0, 5000);
}
public void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
worker.RunWorkerAsync();
}
private void MyTimerCallBack(object state)
{
DisplayWegingInfo();
CaculateTimeBetweenWegingen();
}
The button gets refilled with new values every 1 sec trough a other timer. "DuurStilstand" is a dependency property
private void FillDuurStilstandRegistrationBtn()
{
TimeSpan tsSec = TimeSpan.FromSeconds(stopWatch.Elapsed.Seconds);
TimeSpan tsMin = TimeSpan.FromMinutes(stopWatch.Elapsed.Minutes);
TimeSpan tsHour = TimeSpan.FromMinutes(stopWatch.Elapsed.Hours);
if (GlobalObservableCol.regBtns.Count >= 1
&& GlobalObservableCol.regBtns[GlobalObservableCol.regBtns.Count - 1].StopWatchActive == true)
{
GlobalObservableCol.regBtns[GlobalObservableCol.regBtns.Count - 1].DuurStilstand =
String.Format("{0:D2}:{1:D2}:{2:D2}", tsHour.Hours, tsMin.Minutes, tsSec.Seconds);
}
}
All the above code is written in a separate c# class.
How exactly do i make this code work with BackGroundWorker and how / where to update the GUI with Dispatcher/Invoke. Been trying for a long while and i cannot seem to solve this issue atm.
I have also seen that the Complete method of the BackGroundWorker can be used to update the GUI, but not sure how exactly. The buttons get created and saved in a ObservableCollection.
public static ObservableCollection<RegistrationButton> regBtns = new ObservableCollection<RegistrationButton>();
Some examples would be most useful. Since i know more or less what has to been done but not exactly sure how to implement it.
Best Regards,
Jackz
I don't understand the meaning of your app but you'll be able to update UI like this
public void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.ApplicationIdle, new Action(() =>
{
//do your stuff
}));
}
Maybe the Rendering event should help you to deal with the UIThread.
CompositionTarget.Rendering += (s, args) =>
{
//do your stuff
};
Hope it help

How to implement a blinking label on a form

I have a form that displays queue of messages and number this messages can be changed. Really I want to blink label (queue length) when the number of messages were increased to improve form usability.
Should I implement custom control and use additional thread or timer to change color of label? Has anybody implemented so functionality? What is the best solution (less resources and less performance degradation) to implement so behaviour?
SOLUTION:
Form's component with timer that can restrict number of animations per second and implement fade out effect to external control background color.
The following is blinking using async and await
private async void Blink(){
while (true){
await Task.Delay(500);
label1.BackColor = label1.BackColor == Color.Red ? Color.Green : Color.Red;
}
}
I know this is a really old post, but anyone looking for something a little more versatile than the Boolean solutions posted may get some use out of the following:
using System.Diagnostics;
using System.Threading.Tasks;
private async void SoftBlink(Control ctrl, Color c1, Color c2, short CycleTime_ms, bool BkClr)
{
var sw = new Stopwatch(); sw.Start();
short halfCycle = (short)Math.Round(CycleTime_ms * 0.5);
while (true)
{
await Task.Delay(1);
var n = sw.ElapsedMilliseconds % CycleTime_ms;
var per = (double)Math.Abs(n - halfCycle) / halfCycle;
var red = (short)Math.Round((c2.R - c1.R) * per) + c1.R;
var grn = (short)Math.Round((c2.G - c1.G) * per) + c1.G;
var blw = (short)Math.Round((c2.B - c1.B) * per) + c1.B;
var clr = Color.FromArgb(red, grn, blw);
if (BkClr) ctrl.BackColor = clr; else ctrl.ForeColor = clr;
}
}
Which you can call like such:
SoftBlink(lblWarning, Color.FromArgb(30, 30, 30), Color.Red,2000,false);
SoftBlink(lblSoftBlink, Color.FromArgb(30, 30, 30), Color.Green, 2000,true);
Timer timer = new Timer();
timer.Interval = 500;
timer.Enabled = false;
timer.Start();
if( messagesNum > oldMessagesNum)
timer.Tick += new EventHandler( timer_Tick );
else
timer.Tick -= timer_Tick;
void timer_Tick( object sender, EventArgs e )
{
if(messageLabel.BackColor == Color.Black)
messageLabel.BackColor = Color.Red;
else
messageLabel.BackColor = Color.Black;
}
Here is a pretty simple implementation that would work inside your form. You could also create a custom control with the same code and just throw the Timer.Start() into a method for that control.
Create your own UserControl for this, one that inherits from Label instead of from Control directly. Add a StartBlinking method, in which you start a Timer object whose tick event alters the style of the label (changing the BackgroundColor and ForegroundColor properties each time to create the blink effect).
You could also add a StopBlinking method to turn it off, or you could have your Timer stop itself after 5 seconds, perhaps.
You can create a custom component and events to start blinking --which I think is a good solution. The Blinking you can implement with a timer.
Can you use an animated .gif instead (perhaps as the background of the number)? it would make it look like old school web pages, but it might work.
You can use Timer class here.
Here what I have implemented.
Label color blinking on Button_click Event.
//click event on the button to change the color of the label
public void buttonColor_Click(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Interval = 500;// Timer with 500 milliseconds
timer.Enabled = false;
timer.Start();
timer.Tick += new EventHandler(timer_Tick);
}
void timer_Tick(object sender, EventArgs e)
{
//label text changes from 'Not Connected' to 'Verifying'
if (labelFirst.BackColor == Color.Red)
{
labelFirst.BackColor = Color.Green;
labelFirst.Text = "Verifying";
}
//label text changes from 'Verifying' to 'Connected'
else if (labelFirst.BackColor == Color.Green)
{
labelFirst.BackColor = Color.Green;
labelFirst.Text = "Connected";
}
//initial Condition (will execute)
else
{
labelFirst.BackColor = Color.Red;
labelFirst.Text = "Not Connected";
}
}
this is how i ended up doing it
public partial class MemberDisplay : Form
{
public string Input;
public int MASS_STOP = 1;
public MemberDisplay(string msg)
{
InitializeComponent();
State_Entry();
Input = msg;
}
public void State_Entry()
{
this.SpecialFocus.Select();
this.lbl_TimerTest.Hide();
}
private async void RunBlinkyTest(string msg)
{
while (msg == "GO" && (MASS_STOP == 0))
{
await Task.Delay(500);
lbl_TimerTest.ForeColor =
lbl_TimerTest.ForeColor == Color.Red ?
Color.Black :
Color.Red;
if (msg == "STOP" && (MASS_STOP == 1)) { return; }
}
}
private void btn_TimeTest_Click(object sender, EventArgs e)
{
if (btn_TimeTest.Text == "GO")
{
this.lbl_TimerTest.Show();
MASS_STOP = 0;
RunBlinkyTest("GO");
btn_TimeTest.Text = "STOP";
return;
}
if (btn_TimeTest.Text == "STOP")
{
MASS_STOP = 1;
RunBlinkyTest("STOP");
this.lbl_TimerTest.ForeColor = Color.Black;
this.lbl_TimerTest.Hide();
btn_TimeTest.Text = "GO";
return;
}
}
}

Categories

Resources