Please, help me to understand how I could stop attempts of executing MethodOne() inside a dispatcherTimer.Tick event handler of WPF DispatcherTimer after first unsuccessful attempt of doing it.
TimeSpan ts = new TimeSpan(0, 0, 5);
DispatcherTimer dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = ts;
dispatcherTimer.Start();
...
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
try
{
MethodOne()
}
catch (Exception)
{
// Here I would like prevent code from trying to execute MethodOne()
}
}
I would like to set some lock or to stop timer, but trying to do it I faced problems of visibility of other code from inside a Try-Catch construction and not sure how to overcome it correctly.
That's what the "sender" argument is for:
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
try
{
MethodOne()
}
catch (Exception)
{
(sender as DispatcherTimer).Stop();
}
}
Related
How can I implement a countdown timer in my Windows Phone 8.1 app? There seems to be no information available for it. All I could find works for either a Windows Forms application or a Windows Application, but none of them seems to be working on the phone app.This is what I am doing-
namespace Timer
{
public partial class MainPage : Page
{
DispatcherTimer mytimer = new DispatcherTimer();
int currentcount = 0;
public MainPage()
{
InitializeComponent();
mytimer = new DispatcherTimer();
mytimer.Interval = new TimeSpan(0, 0, 0, 1, 0);
mytimer.Tick += new EventHandler(mytime_Tick);
//HERE error comes Cannot implicitly convert type System.EventHandler to System.EventHandler<object>
}
private void mytime_Tick(object sender,EventArgs e)
{
timedisplayBlock.Text = currentcount++.ToString();
}
private void startButton_Click(object sender, RoutedEventArgs e)
{
mytimer.Start();
}
}
}
But it gives me this error-
Cannot implicitly convert type System.EventHandler to System.EventHandler<object>
Should your increment not be written as
timedisplayBlock.Text = (++currentcount).ToString();
Or
currentcount++;
timedisplayBlock.Text = currentcount.ToString();
I don't think the increment will matter too much but still should be written correctly to ensure you do not leave yourself a count behind.
- See Sergiol's issue with David's answer on the link below https://stackoverflow.com/a/7848129/2110465
The other thing i have noticed is that you are initializing the DispatcherTimer twice...
DispatcherTimer mytimer = new DispatcherTimer();
...
..
mytimer = new DispatcherTimer();
It is better practice to initialize upon the instance to save overhead, though depending on the scope of use. Given i am not aware of how the rest of your code uses it, i suggest it be rewritten as follows
namespace Timer
{
public partial class MainPage : Page
{
DispatcherTimer mytimer = new DispatcherTimer();
int currentcount = 0;
public MainPage()
{
InitializeComponent();
mytimer.Interval = new TimeSpan(0, 0, 0, 1, 0);
mytimer.Tick += new EventHandler(mytime_Tick);
}
private void mytime_Tick(object sender, EventArgs e)
{
timedisplayBlock.Text = (++currentcount).ToString();
}
private void startButton_Click(object sender, RoutedEventArgs e)
{
mytimer.Start();
}
}
}
Saying all of the above, i could not reproduce the fault when replicated...
EDIT - This may be your issue (https://stackoverflow.com/a/16636862/2110465)
You misspelled the event handler name the event handler definition needs to be changing too, it should be:
mytimer.Tick += mytime_Tick; // removed the 'r'
Change
private void mytimer_Tick(object sender, EventArgs e)
to
private void mytimer_Tick(object sender, object e).
I have a background worker which i am using to perform some task. Its working as expected. However, i have a timer that i want to add and make it start the bw and counting like 10 seconds after page load. I put my timer.Interval to 10000. the timer has a tick events as below
private DateTime dateETA;
private void TimerEventHandler(object sender, EventArgs e)
{
while (bw.CancellationPending ==false)
{
if (timerPro.Enabled == true)
{
dateETA = Convert.ToDateTime("1/1/0001 00:00:00");
dateETA = dateETA.AddMilliseconds(timerPro.Interval);
lblETA.Visible = true;
lblETA.Text = "Elapsed Time : " + Convert.ToString(dateETA.TimeOfDay);
// SetText("timer");
}
}
}
My background worker async is on the page contructor method and therefore run on load. just like below
if (bw.IsBusy != true)
{
this.btnPause.Enabled = true;
this.btnStop.Enabled = true;
btnStart.Enabled = false;
// timerPro.Start();
bw.RunWorkerAsync();
}
I wanted to start the timer together with my task therefore i put it before my bw.async . Then i realized the timer tick events does not fire when put before or within the dowork method of the background worker. I thought may be the bw thread is blocking the event from firing then i use an invoke method like below within the dowork in my attempt to start the timer or trigger the tick event of the timer.
this.Invoke((MethodInvoker)(() => { timerPro.Enabled = true; }));
It still does not fire. I am confused and any help or alternative would be appreciated.
I think you just want a running elapsed timer while the backgroundworker does its thing?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private System.Diagnostics.Stopwatch SW = new System.Diagnostics.Stopwatch();
private void Form1_Load(object sender, EventArgs e)
{
timerPro.Interval = 1000;
timerPro.Tick +=new EventHandler(TimerEventHandler);
SW.Start();
timerPro.Start();
bw.RunWorkerAsync();
}
private void TimerEventHandler(object sender, EventArgs e)
{
lblETA.Visible = true;
TimeSpan TS = SW.Elapsed;
string elapsed = String.Format("{0}:{1}:{2}", TS.Hours.ToString("00"), TS.Minutes.ToString("00"), TS.Seconds.ToString("00"));
lblETA.Text = "Elapsed Time : " + elapsed;
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
// ... do some work ...
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
timerPro.Stop();
}
}
what i want to do is pause a video after every 10s
the video should pause after ever 10s till the video ends
the code given below gives unexpected results
the video pauses fine for the firs time (i.e after 10s)
but when i play again it should pause after 10s but in my case it pauses randomly sometimes at 8s,3s 5s and etc
what should i do??
please help
thanks!!
void PlayClick(object sender, EventArgs e)
{
VideoControl.Play();
var dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 10);
dispatcherTimer.Start();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
VideoControl.Pause();
}
Add this in your dispatcherTimer_Tick-Method:
dispatcherTimer.Stop();
Move the following part into the constructor:
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 10);
Make the DispatcherTimer a global variable.
EDIT: Thats how it should look like:
class MyClass
{
private DispatcherTimer _dispatcherTimer; //now your dispatcherTimer is accessible everywhere in this class
public MyClass()
{
_dispatcherTimer = new DispatcherTimer();
_dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
_dispatcherTimer.Interval = new TimeSpan(0, 0, 10);
}
void PlayClick(object sender, EventArgs e)
{
VideoControl.Play();
_dispatcherTimer.Start();
}
void dispatcherTimer_Tick(object Sender, EventArgs e)
{
_dispatcherTimer.Stop();
VideoControl.Pause();
}
}
Bring the declaration of the timer out into a private class variable, move a couple lines to the constructor of the class, and stop the timer in the Tick handler.
The reason you don't want to keep creating the timer is because there are unmanaged resources involved with a timer and so you're closing that loop.
private dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
ctor
{
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 10);
}
void PlayClick(object sender, EventArgs e)
{
VideoControl.Play();
dispatcherTimer.Start();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
dispatchTimer.Stop();
VideoControl.Pause();
}
Try with following code in Tick event:
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
(sender as DispatcherTimer).Stop();
VideoControl.Pause();
}
You can make dispatcherTimer object outside Playclick event and only put Start() method inside PlayClick event in following way:
var dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
public Form1() //// form constructor where you are handling these all event....
{
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 10);
}
void PlayClick(object sender, EventArgs e)
{
VideoControl.Play();
dispatcherTimer .Start();
}
I have a wpf application(No MVVM), this application requires several background thread(Runs with specific time interval).
These thread should be on Application Level i.e. if user is on any WPF Window, these threads should be active.
Basically these thread will are using external resources so locking is also required.
Kindly tell me the best way to do this.
If you want to execute an action periodically in a WPF application you can use the DispatcherTimer class.
Put your code as the handler of the Tick event and set the Interval property to whatever you need. Something like:
DispatcherTimer dt = new DispatcherTimer();
dt.Tick += new EventHandler(timer_Tick);
dt.Interval = new TimeSpan(1, 0, 0); // execute every hour
dt.Start();
// Tick handler
private void timer_Tick(object sender, EventArgs e)
{
// code to execute periodically
}
private void InitializeDatabaseConnectionCheckTimer()
{
DispatcherTimer _timerNet = new DispatcherTimer();
_timerNet.Tick += new EventHandler(DatabaseConectionCheckTimer_Tick);
_timerNet.Interval = new TimeSpan(_batchScheduleInterval);
_timerNet.Start();
}
private void InitializeApplicationSyncTimer()
{
DispatcherTimer _timer = new DispatcherTimer();
_timer.Tick += new EventHandler(AppSyncTimer_Tick);
_timer.Interval = new TimeSpan(_batchScheduleInterval);
_timer.Start();
}
private void IntializeImageSyncTimer()
{
DispatcherTimer _imageTimer = new DispatcherTimer();
_imageTimer.Tick += delegate
{
lock (this)
{
ImagesSync.SyncImages();
}
};
_imageTimer.Interval = new TimeSpan(_batchScheduleInterval);
_imageTimer.Start();
}
These three threads a intialized on App_OnStart
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
try
{
_batchScheduleInterval = Convert.ToInt32(ApplicationConfigurationManager.Properties["BatchScheduleInterval"]);
}
catch(InvalidCastException err)
{
TextLogger.Log(err.Message);
}
Helper.SaveKioskApplicationStatusLog(Constant.APP_START);
if (SessionManager.Instance.DriverId == null && _batchScheduleInterval!=0)
{
InitializeApplicationSyncTimer();
InitializeDatabaseConnectionCheckTimer();
IntializeImageSyncTimer();
}
}
Hi I am working with Windows.Forms.Timer with Web Application . I create Timer.Tick event handler to handle Timer_Tick but I am not successfull. I don't get any error but I can not get result even. Here is my code
System.Windows.Forms.Timer StopWatchTimer = new System.Windows.Forms.Timer();
Stopwatch sw = new Stopwatch();
public void StopwatchStartBtn_Click(object sender, ImageClickEventArgs e)
{
StopWatchTimer.Enabled = true;
StopWatchTimer.Interval = 1;
StopWatchTimer.Start();
this.StopWatchTimer.Tick += new EventHandler(StopWatchTimer1_Tick);
sw.Start();
}
protected void StopWatchStopBtn_Click(object sender, ImageClickEventArgs e)
{
StopWatchTimer.Stop();
sw.Reset();
StopWatchLbl.Text = "00:00:00:000";
}
public void StopWatchTimer1_Tick(object sender,EventArgs e)
{
TimeSpan elapsed = sw.Elapsed;
StopWatchLbl.Text = string.Format("{0:00}:{1:00}:{2:00}:{3:00}",
Math.Floor(elapsed.TotalHours),
elapsed.Minutes,
elapsed.Seconds,
elapsed.Milliseconds);
}
From the MSDN documentation for Windows Forms Timer (emphasis mine):
Implements a timer that raises an event at user-defined intervals. This timer is optimized for use in Windows Forms applications and must be used in a window.
This timer will not work in a web application. You'll need to use another class, like System.Timers.Timer. This has it's own pitfalls, however.
Did you try defining the Tick event prior to starting the timer?
this.StopWatchTimer.Tick += new EventHandler(StopWatchTimer1_Tick);
StopWatchTimer.Start();
public partial class TestFrom : Form
{
private Thread threadP;
private System.Windows.Forms.Timer Timer = new System.Windows.Forms.Timer();
private string str;
public TestFrom()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Timer.Interval =100;
Timer.Tick += new EventHandler(TimeBussiness);
Timer.Enabled = true;
Timer.Start();
Timer.Tag = "Start";
}
void TimeBussiness(object sender, EventArgs e)
{
if (threadP.ThreadState == ThreadState.Running)
{
Timer.Stop();
Timer.Tag = "Stop";
}
else
{
//do my bussiness1;
}
}
private void button3_Click(object sender, EventArgs e)
{
ThreadStart threadStart = new ThreadStart(Salver);
threadP= new Thread(threadStart);
threadP.Start();
}
private void Salver()
{
while (Timer.Tag == "Stop")
{
}
//do my bussiness2;
Timer.Start();
Timer.Tag = "Start";
}
}