I tell the Timer to start in the constructor. It starts, but when it reaches its Timer.Elapsed event it only runs the first if statement in the method. I've checked to see if isWatching is true, and it is, but it still skips it entirely. It doesn't even reach the if(isWatching) line.
Code:
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public SessionManager SM { get; private set; }
public MainWindow()
{
SM = new SessionManager();
SM.NewDayEvent += SplitSession;
///code
}
}
SessionManager.cs (Some variables have been omitted from this post):
public class SessionManager : INotifyPropertyChanged
{
public delegate void NewDayEventHandler(object sender, EventArgs ea);
public event NewDayEventHandler NewDayEvent;
private bool _isWatching;
private Timer _timer;
private bool isWatching
{
get
{
return _isWatching;
}
set
{
_isWatching = value;
if (!_isWatching)
{
_clockWatch.Stop();
}
else
{
_clockWatch.Start();
}
}
}
#endregion
public SessionManager()
{
_clockWatch = new Stopwatch();
_timer = new Timer(1000);
_timer.Elapsed += timerElapsed;//focus on this here
_isWatching = false;
current_time = new DateTime();
CurrentTime = DateTime.Now;
_timer.Start();
}
public void timerElapsed(object sender, ElapsedEventArgs e)
{
CurrentTime = DateTime.Now;
if (CurrentTime.TimeOfDay == TimeSpan.Parse("9:32 AM") && NewDayEvent != null)
{
NewDayEvent(this, new EventArgs());
}
if (isWatching)
{
if (CurrentSession != null)
{
//update the timespent variable of the current timeEntry
if (CurrentSession.currentTimeEntry != null)
{
CurrentSession.currentTimeEntry.TimeSpent = _clockWatch.Elapsed;
calculateTotalTime();
CalculateFilteredTimeSpent();
}
}
}
}
}
You aren't using the correct format while calling TimeSpan.Parse(). The right way to do what you are trying to is:
TimeSpan.Parse("9:32")
Your current code snippet throws a System.FormatException:
A first chance exception of type 'System.FormatException' occurred in mscorlib.dll
However for what you are trying to achieve, trigger an action once every day at a particular time, the above method might not be the best since the chances of it succeeding are very less. The timer will run every 1000 ms and then return the current time of day which has milliseconds included. So the timer elapsed event could be called at 9:32.0001 and might never pass the condition. A better alternative is probably:
if (CurrentTime.TimeOfDay >= TimeSpan.Parse("9:32") && NewDayEvent != null)
This will trigger more than once after that time has elapsed, so you could add a flag which keeps track of what day the last event was processed.
Alternatively you could also look at ScheduleAction in .NET 4.5 or some of the solutions here.
Related
I have this class
public class ResetClock
{
public delegate void ResetFunc();
private ResetFunc m_ResetFunc;
private event ResetFunc Reseted;
private Timer m_Timer;
public ResetClock(int second)
{
double r = second * 1000;
m_Timer = new Timer(r);
m_Timer.AutoReset = false;
m_Timer.Elapsed += new ElapsedEventHandler(onTimerTick);
Reset();
}
public void SetResetMethod(ResetFunc method)
{
m_ResetFunc = method;
}
public void Terminate()
{
m_Timer.Stop();
m_Timer.Dispose();
m_Timer = null;
}
private void onTimerTick(object sender, ElapsedEventArgs e)
{
if (m_ResetFunc == null)
{
if (Reseted != null) Reseted();
}
else
{
m_ResetFunc();
}
Reset();
}
#region Public
public void Reset()
{
m_Timer.Reset();
}
#endregion
}
internal static class TimerEx{
public static void Reset(this Timer timer){
timer.Stop();
timer.Start();
}
}
My application is showing the reset page when this class reaches the seconds defined in the contractor. when a Reset() method calls, the Timer should reset the it self and begin the timer from 0.
for some reason after the application is running few days the reset event is firing after few seconds and not the number of seconds that i defined in the first application initialization
does anyone have any idea....??? I braking my head through the wall to find the answer..
I have implemented a SqlListener class that uses SqlDependency to wait for changes in SQL database. At one point in my business workflow I need to wait for a record turning up in the database. The SqlListener triggers an event when requested record is found. This works fine. I can make it work by entering a While-loop and wait until I detect the event being returned. But this is not ideal design. It makes the processor spin a lot in vain.
I would like to wait for the event in a more intelligent manner. I read a lot of suggestions on using Task, NotificationDelegate, ManualResetEvent, etc. .... but I was not able to get it all together.
A simplified example will probably make it easier to understand. This is my current setup that works. But if possible I would like to get rid of the ugly while loop.
private const int MaxWaitTime = 5;
private SqlListener<RecordType> _recordListener;
private RecordType _record;
/// <summary>
/// Request a record and wait until it is found.
/// </summary>
public RecordType GetRecordAwait(int requestedId)
{
// Initiate listening for record
_recordListener = new SqlListener<RecordType>();
_recordListener.SqlModified += SqlListener_SqlModified;
_recordListener.StartListening(requestedId);
// Wait until record is found
var startTime = DateTime.Now;
while (_record == null &&
DateTime.Now.Subtract(startTime).TotalSeconds < MaxWaitTime)
{
Thread.Sleep(1);
}
// Stop listening
_recordListener.SqlModified -= SqlListener_SqlModified;
_recordListener.Dispose();
_recordListener = null;
// Return record
return _record;
}
private void SqlListener_SqlModified(object sender, SqlModifiedArgs args)
{
_record = (RecordType)args.Record;
}
Instead of using While, you could go with Timer and events. Something like:
public class ListenerWaiting
{
public ListenerWaiting(int waitingTimeSeconds)
{
_waitSeconds = waitingTimeSeconds;
}
private int _waitSeconds;
private System.Timers.Timer _timer;
private Listener _listener;
public event EventHandler<string> ListenerDone;
public void Listen(int listeningPeriodSeconds)
{
_listener = new Listener(listeningPeriodSeconds * 1000);
_listener.ListenerCompleted += ListenerListenerCompleted;
_timer = new System.Timers.Timer(_waitSeconds * 1000) {Enabled = true};
_timer.Elapsed += TimerElapsed;
}
void ListenerListenerCompleted(object sender, string e)
{
StopTimer();
StopListener();
if (ListenerDone != null)
ListenerDone(this, "Waiting success! Message was: " + e);
}
void TimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
StopTimer();
StopListener();
if (ListenerDone != null)
ListenerDone(this, "Waited longer than set, aborted waiting...");
}
private void StopTimer()
{
_timer.Stop();
_timer.Elapsed -= TimerElapsed;
_timer = null;
}
private void StopListener()
{
_listener.ListenerCompleted -= ListenerListenerCompleted;
_listener = null;
}
}
public class Listener
{
private System.Timers.Timer _timer;
private string _listeningPeriodSeconds;
public event EventHandler<string> ListenerCompleted;
public Listener(int listeningPeriodSeconds)
{
_listeningPeriodSeconds = listeningPeriodSeconds.ToString();
_timer = new System.Timers.Timer(listeningPeriodSeconds) { Enabled = true };
_timer.Elapsed += TimerElapsed;
}
private void TimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
_timer.Elapsed -= TimerElapsed;
_timer = null;
if (ListenerCompleted != null)
ListenerCompleted(this, _listeningPeriodSeconds);
}
}
...and then consume it with:
static void Main(string[] args)
{
var wait = new ListenerWaiting(5);
wait.ListenerDone += WaitListenerDone;
wait.Listen(3);
Console.ReadLine();
}
static void WaitListenerDone(object sender, string e)
{
Console.WriteLine(e);
}
I guess I could find better names for classes, but you'll get the idea ;)
In fact the solution was more simple than I first thought. When I rephrased my question and searched again I found it. The ManualResetEvent as mentioned already in my question turned out to be the simplest way to solve it.
All I had to do was to add a ManualResetEvent and set it to wait ;-)
private const int MaxWaitTime = 5000;
private SqlListener<RecordType> _recordListener;
private RecordType _record;
private readonly ManualResetEvent _recordWaiter = new ManualResetEvent(false);
/// <summary>
/// Request a record and wait until it is found.
/// </summary>
public RecordType GetRecordAwait(int requestedId)
{
// Initiate listening for record
_recordListener = new SqlListener<RecordType>();
_recordListener.SqlModified += SqlListener_SqlModified;
_recordListener.StartListening(requestedId);
// Wait synchronously until record is found
_recordWaiter.WaitOne(MaxWaitTime);
// Stop listening
_recordListener.SqlModified -= SqlListener_SqlModified;
_recordListener.Dispose();
_recordListener = null;
// Return record
return _record;
}
private void SqlListener_SqlModified(object sender, SqlModifiedArgs args)
{
_record = (RecordType)args.Record;
_recordWaiter.Set();
}
I have a WPF user control called TimerUserControl where contains a timer. And I have another user control where show questions, this one has a NextQuestion function.
The timer has 2 minutes like an interval, and I'd like to invoke the NextQuestion function when it has done. I think I have to use delegates, but I'm not sure.
UPDATE 1:
public partial class TimeUserControl : UserControl
{
public int _totalSeconds;
public int _secondsRemaining;
public DispatcherTimer timerSecondsLeft;
public TimeUserControl()
{
InitializeComponent();
timerSecondsLeft = new DispatcherTimer();
timerSecondsLeft.Tick += new EventHandler(timerSecondsLeft_Tick);
timerSecondsLeft.Interval = new TimeSpan(0, 0, 1);
}
public bool TimesUp
{
get;
set;
}
public void SetSeconds(int seconds)
{
timerSecondsLeft.Stop();
if (seconds == 0)
{
TimeTextBlock.Text = "There's no time! Hurray";
}
else
{
_totalSeconds = seconds;
_secondsRemaining = seconds;
TimeTextBlock.Text = string.Format("It remains {0} seconds. Don't take long!", _totalSeconds);
timerSecondsLeft.Start();
}
}
public void timerSecondsLeft_Tick(object sender, EventArgs e)
{
_secondsRemaining--;
if (_secondsRemaining <= 0)
{
timerSecondsLeft.Stop();
TimesUp = true;
TimeTextBlock.Text = "Time's up. Press Enter to next problem.";
// HERE WILL INVOKE NEXTQUESTION FUNCTION
}
else
{
TimeTextBlock.Text = string.Format("It remains {0} seconds. Don't take long!", _secondsRemaining);
}
}
}
Look in the code, the comment is this possible ussing delegates?
So you need to do a few things. You have to add some code to you're user control.
// Declare this outside your usercontrol class
public delegate void TimerExpiredEventHandler(object sender, EventArgs e);
This is what needs to be added to your code for the user control.
public partial class TimerUserControl : UserControl
{
public event TimerExpiredEventHandler Expired;
public void OnExpired(EventArgs e)
{
if (Expired != null)
Expired(this, e);
}
public void timerSecondsLeft_Tick(object sender, EventArgs e)
{
_secondsRemaining--;
if (_secondsRemaining <= 0)
{
timerSecondsLeft.Stop();
TimesUp = true;
TimeTextBlock.Text = "Time's up. Press Enter to next problem.";
// Fire the event here.
OnExpired(EventArgs.Empty);
}
else
{
TimeTextBlock.Text = string.Format("It remains {0} seconds. Don't take long!", _secondsRemaining);
}
}
}
Now you need to subscribe to this event inside whatever is calling this usercontrol in the first place.
public partial class ParentForm : Form
{
private void ParentForm_Load(object sender, EventArgs e)
{
var timer = new TimerUserControl();
//Subscribe to the expired event that we defined above.
timer.Expired += new EventArgs(Timer_Expired);
}
public void Timer_Expired(object sender, EventArgs e)
{
//Handle the timer expiring here. Sounds like you are calling another function, so do that here.
}
}
Use the TreeHelper to hunt up the tree for a shared Parent and then down the tree for the User Control you want. Something like this pseudo code:
this.Timer = new System.Windows.Threading.DispatcherTimer
{
Interval = new TimeSpan(0, 0, 1)
};
this.Timer.Tick += (s, e) =>
{
var _Control = s as MyFirstControl;
var _Other = LogicalTreeHelper.GetChildren(_Control.Parent)
.Cast<FrameworkElement>().Where(x => x.Name == "FindIt")
.First<MySecondControl>();
_Other.DoMethod();
};
Best of luck!
i would probably break out the functionality of the timer control here; something like this (note: i am writing this on-the-fly so let me know if it doesn't work as-is, and i will help correct any issues):
// a simple delegate to report the amount of time remaining
// prior to the expiration of the major tick interval; zero
// indicates that this major tick has elapsed.
public delegate void delegateMajorMinorTimerTick
(
int TimeRemaining_sec, ref bool CancelTimer
);
// you could use milliseconds for the interval settings to get
// better granularity, or you could switch to setting the major
// interval instead, however that approach would require a bit
// more checking to make sure the control has sane settings.
public class MajorMinorTimer
{
// this sets the interval in seconds between the
// "minor" ticks used for intermediate processing
// these are the "inner" intervals of the timer
private int myMinorTickInterval_sec;
public int MinorTickInterval_sec
{
get { return myMinorTickInterval_sec; }
}
// this sets the number of minor ticks between the
// expiration of the major interval of the timer.
// the "outer" interval of the timer
private int myMinorTicksPerMajorTick;
public int MinorTicksPerMajorTick
{
get { return myMinorTicksPerMajorTick; }
}
public MajorMinorTimer
(
int parMinorTickInterval_sec,
int parMinorTicksPerMajorTick
)
{
MinorTickInterval_sec = parMinorTickInterval_sec;
MinorTicksPerMajorTick = parMinorTicksPerMajorTick;
}
private DispatcherTimer myBackingTimer;
private int myMinorTickCount;
public void Start()
{
// reset the minor tick count and start the dispatcher
// timer with some reasonable defaults.
myMinorTickCount = 0;
myBackingTimer =
new DispatcherTimer
(
TimeSpan.FromSeconds(MinorTickInterval_sec),
DispatcherPriority.Normal,
new EventHandler(myBackingTimer_Tick),
Dispatcher.CurrentDispatcher
);
myBackingTimer.Start();
}
public event delegateMajorMinorTimerTick onTick;
private bool FireMajorMinorTimerTick(int TimeRemaining_sec)
{
// allows the timer sink to cancel the timer after this
// call; just as an idea, also could be handled with a
// call to Stop() during the event, but this
// simplifies handling a bit (at least to my tastes)
bool CancelTimer = false;
if (onTick != null)
onTick(TimeRemaining_sec, ref CancelTimer);
return CancelTimer;
}
private void myBackingTimer_Tick(object Sender, EventArgs e)
{
// since we are using a DispatchTimer with settings that should
// do not suggest the possibility of synchronization issues,
// we do not provide further thread safety. this could be
// accomplished in the future if necessary with a lock() call or
// Mutex, among other methods.
++myMinorTickCount;
int TicksRemaining = myMinorTickCount - MinorTicksPerMajorTick;
bool Cancel =
FireMajorMinorTimerTick(TicksRemaining * MinorTickInterval_sec);
if (TicksRemaining == 0)
myMinorTickCount = 0;
if (Cancel)
Stop();
}
public void Stop()
{
myBackingTimer.Stop();
}
}
then, assuming, say, a Quiz control, the timer is used like so:
public void QuestionTimerSetup()
{
// sets up a timer to fire a minor tick every second
// with a major interval of 5 seconds
MajorMinorTimer timerQuestion = new MajorMinorTimer(1, 5);
timerQuestion.onTick +=
new delegateMajorMinorTimerTick(QuestionControl_QuestionTimerTick);
}
// ...
public void QuestionControl_OnTick(int TimeRemaining_sec, ref bool CancelTimer)
{
if (TimeRemaining_sec > 0)
{
tblockQuizStatus.Text =
string.Format("There are {0} seconds remaining.", TimeRemaining_sec);
}
else
{
// just for an example
if (NoMoreQuestions)
{
CancelTimer = true;
HandleEndOfQuiz();
tblockQuizStatus.Text =
"Time's up! The quiz is complete!";
}
else
{
tblockQuizStatus.Text =
"Time's up! Press Enter to continue to the next problem.";
}
}
}
another option (rather than, or in addition to, events) in implementing this might be to add an Action taking the time remaining in the major interval for the minor interval action, an Action for the major interval action, and a Func<bool> that checks the stop condition, allowing the user to perform the desired actions in that way. like this:
public class MajorMinorTimer
{
public MajorMinorTimer
(
int parMinorTimerInterval_sec,
int parMinorTicksPerMajorTick,
Action<int> parMinorTickAction,
Action parMajorTickAction,
Func<bool> parShouldStopFunc
)
{
myMinorTimerInterval_sec = parMinorTimerInterval_sec;
myMinorTicksPerMajorTick = parMinorTicksPerMajorTick;
myMinorTickAction = parMinorTickAction;
myMajorTickAction = parMajorTickAction;
myShouldStopFunc = parShouldStopFunc;
}
private Action<int> myMinorTickAction;
private Action myMajorTickAction;
private Func<bool> myShouldStopFunc;
private void myBackingTimer_OnTick()
{
++myMinorTickCount;
int TicksRemaining = myMinorTickCount - MinorTicksPerMajorTick;
if (TicksRemaining == 0)
myMajorTickAction();
else
myMinorTickAction(TicksRemaining * MinorTickInterval_sec);
bool Cancel = myShouldStopFunc();
if (TicksRemaining == 0)
myMinorTickCount = 0;
if (Cancel)
Stop();
}
}
and then in the quiz code instead of hooking up the event do something like:
public void QuestionTimerSetup()
{
MajorMinorTimer timerQuestion =
new MajorMinorTimer
(
1,
5,
// major interval action
(SecsRemaining) =>
{
tblockQuizStatus.Text =
string.Format
(
"There are {0} seconds remaining.", SecsRemaining
);
},
// minor interval action
() =>
{
if (NoMoreQuestions)
{
tblockQuizStatus.Text =
"Time's up! This completes the quiz!";
HandleEndOfQuiz();
}
else
{
tblockQuizStatus.Text =
"Time's up! Press Enter to continue to next question.";
}
},
// timer cancel check function
() =>
IsEndOfQuizHandled()
);
}
ive been working on a program. i has 3 classes. 2 of the classes have timers that repeat at different intervals and once one "cycle" of the timer is done it raises an event with a string as return. the 3rd class subscribes to the events from the other two timer classes and prints them to screen. it works great!
but my issue is that it prints them separately. say currently the first timer class runs and then raises "hello" every 2 minutes and the other class "dog" every second. then every time an event is raised it prints the raised event to console. i would want it to instead print "hellodog" every second.
i was thinking: so each time a timer fires it will raise an event and update a string in the "output" class with the current value, then make another timer that goes off every second, this timer will read both the updated strings together as one output like "hellodog". is this possible if it is this is the easiest way i think. how would i achieve this idea?
if it is confusing i will clarify.
namespace Final
{
public class Output
{
public static void Main()
{
var timer1 = new FormWithTimer();
var timer2 = new FormWithTimer2();
timer1.NewStringAvailable += new EventHandler<BaseClassThatCanRaiseEvent.StringEventArgs>(timer1_NewStringAvailable);
timer2.NewStringAvailable += new EventHandler<BaseClassThatCanRaiseEvent.StringEventArgs>(timer2_NewStringAvailable);
Console.ReadLine();
}
static void timer1_NewStringAvailable(object sender, BaseClassThatCanRaiseEvent.StringEventArgs e)
{
var theString = e.Value;
//To something with 'theString' that came from timer 1
Console.WriteLine(theString);
}
static void timer2_NewStringAvailable(object sender, BaseClassThatCanRaiseEvent.StringEventArgs e)
{
var theString2 = e.Value;
//To something with 'theString2' that came from timer 2
Console.WriteLine(theString2);
}
}
public abstract class BaseClassThatCanRaiseEvent
{
public class StringEventArgs : EventArgs
{
public StringEventArgs(string value)
{
Value = value;
}
public string Value { get; private set; }
}
//The event itself that people can subscribe to
public event EventHandler<StringEventArgs> NewStringAvailable;
protected void RaiseEvent(string value)
{
var e = NewStringAvailable;
if (e != null)
e(this, new StringEventArgs(value));
}
}
public partial class FormWithTimer : BaseClassThatCanRaiseEvent
{
Timer timer = new Timer();
public FormWithTimer()
{
timer = new System.Timers.Timer(200000);
timer.Elapsed += new ElapsedEventHandler(timer_Tick); // Everytime timer ticks, timer_Tick will be called
timer.Interval = (200000); // Timer will tick evert 10 seconds
timer.Enabled = true; // Enable the timer
timer.Start(); // Start the timer
}
void timer_Tick(object sender, EventArgs e)
{
...
RaiseEvent(gml.ToString());
}
}
public partial class FormWithTimer2 : BaseClassThatCanRaiseEvent
{
Timer timer = new Timer();
public FormWithTimer2()
{
timer = new System.Timers.Timer(1000);
timer.Elapsed += new ElapsedEventHandler(timer_Tick2); // Everytime timer ticks, timer_Tick will be called
timer.Interval = (1000); // Timer will tick evert 10 seconds
timer.Enabled = true; // Enable the timer
timer.Start(); // Start the timer
}
void timer_Tick2(object sender, EventArgs e)
{
...
RaiseEvent(aida.ToString());
}
}
}
You can use the same event handler for both timers. And construct the output by identifying the senders. (Didn't test the code for syntax errors.)
private static string timer1Value = string.Empty;
private static string timer2Value = string.Empty;
private static FormWithTimer timer1;
private static FormWithTimer2 timer2;
public static void Main()
{
timer1 = new FormWithTimer();
timer2 = new FormWithTimer2();
timer1.NewStringAvailable += new EventHandler<BaseClassThatCanRaiseEvent.StringEventArgs>(timer1_NewStringAvailable);
timer2.NewStringAvailable += new EventHandler<BaseClassThatCanRaiseEvent.StringEventArgs>(timer1_NewStringAvailable);
Console.ReadLine();
}
static void timer1_NewStringAvailable(object sender, BaseClassThatCanRaiseEvent.StringEventArgs e)
{
if (sender == timer1)
{
timer1Value = e.Value.ToString();
}
else if (sender == timer2)
{
timer2Value = e.Value.ToString();
}
if (timer1Value != String.Empty && timer2Value != String.Empty)
{
Console.WriteLine(timer1Value + timer2Value);
// Do the string concatenation as you want.
}
When the events are handled in your example they have no access to information about the other events. If you want to have 2 events that update strings, but you want the handler to print data from both updated strings, you need the event handlers to have access to both of those strings. You can either store them in variables on the event handling class, or make them public properties of the classes that are raising the events. That way in either event handler you have access to the updated strings from other events.
Many areas in a project I'm working on have a simple timeout check which basically runs code through a try loop until it succeeds or 10 seconds elapses.
class Timeout {
private readonly DateTime timeoutDate;
public bool FlagSuccess;
public Timeout() {
timeoutDate = DateTime.UtcNow.AddSeconds(10);
flagSuccess = false;
}
public bool continueRunning() {
if (!flagSuccess && DateTime.UtcNow < timeoutDate) return true;
else return false;
}
}
Here is an example of the class in use:
Timeout t = new Timeout();
while (t.continueRunning()) {
try {
//PUT CODE HERE
t.flagSuccess = true;
}
catch(Exception e) {
Console.WriteLine(e.Message);
}
}
Before I implement this, is there a better and more standard way to do this? What I have above is based on my blind intuition.
Use .NETs Timer class(es):
using System.Timers;
public static void Main() {
Timer t = new Timer();
t.Elapsed += new ElapsedEventHandler(ActionWhenFinished);
t.Interval = 10000;
t.Start();
}
public static void ActionWhenFinished()
{
// cancel any action
}
Your Timeout class will block the current thread it is running in, which isn't the case with System.Timer.
I'd suggest changing your loop to a do-while loop, so that you're guaranteed to run the loop at least once even if your thread gets momentarily waylaid between setting up the timeout and starting the loop. Also, I'd suggest that it may be helpful to have the Timeout class include a RemainingMilliseconds property, and maybe RemainingMillisecondsUpTo(Integer N) function, which could be passed to various block-or-timeout routines.
Looks kind of like a busy loop to me, but here's how you'd do it with a StopWatch.
System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
timer.Start();
bool complete;
while( timer.ElapsedMilliseconds < 10000 && !complete)
{
//Do stuff
// and someday... complete = true;
}
You could wrap that up into a simple class as well if you like.
class AgingWait
{
System.Diagnostics.Stopwatch _watch = new System.Diagnostics.Stopwatch();
int maxMilliseconds;
bool forceExpire;
public bool Expired
{
get { return forceExpire || maxMilliseconds < _watch.ElapsedMilliseconds; }
}
public AgingWait(int milli)
{
_watch.Start();
maxMilliseconds = milli;
}
public void Expire()
{
forceExpire = true;
}
}
to use
AgingWait waiter = new AgingWait(1000);
while (!waiter.Expired)
{
if (condition)
waiter.Expire();
}