I am working on iOS Application in Xamarin.
timer1 = new System.Timers.Timer();
timer1.Interval = 1000;
//Play.TouchUpInside += (sender,e)=>
//{
timer1.Enabled = true;
Console.WriteLine("timer started");
timer1.Elapsed += new ElapsedEventHandler(OnTimeEvent);
//}
This is what i have written in viewdidload();
public void OnTimeEvent(object source, ElapsedEventArgs e)
{
count++;
Console.WriteLine("timer tick");
if (count == 30)
{
timer1.Enabled = false;
Console.WriteLine("timer finished");
new System.Threading.Thread(new System.Threading.ThreadStart(() =>
{
InvokeOnMainThread(() =>
{
StartTimer.Text = Convert.ToString(e.SignalTime.TimeOfDay); // this works!
});
})).Start();
}
else
{
//adjust the UI
new System.Threading.Thread(new System.Threading.ThreadStart(() =>
{
InvokeOnMainThread(() =>
{
StartTimer.Text = Convert.ToString(e.SignalTime.TimeOfDay); // this works!
});
})).Start();
timer1.Enabled = false;
Console.WriteLine("timer stopped");
}
}
This is the event I have called when I clicked on button play. I want this method to keep running so that time get updated on the label (starttimer.Text) in the UI. Like Runnable Interface we use in Android, what do we have to use in iOS to keep it running?
Use async - much cleaner (no marshalling to get you back on the main thread again!)
private int _duration = 0;
public async void StartTimer() {
_duration = 0;
// tick every second while game is in progress
while (_GameInProgress) {
await Task.Delay (1000);
_duration++;
string s = TimeSpan.FromSeconds(_duration).ToString(#"mm\:ss");
btnTime.SetTitle (s, UIControlState.Normal);
}
}
//before loading the view
public override void ViewWillAppear(bool animated)
{
...
StartTimer();
}
// when view is loaded
public override void ViewDidLoad()
{
base.ViewDidLoad();
....
UpdateDateTime();
}
private void UpdateDateTime()
{
var dateTime = DateTime.Now;
StartTimer.Text = dateTime.ToString("HH:mm:ss");
}
private void StartTimer()
{
var timer = new Timer(1000);
timer.Elapsed += (s, a) => InvokeOnMainThread(UpdateDateTime);
timer.Start();
}
Related
I am creating a game in visual studio using c sharp and want to add a pop up message saying 'game Over' once the timer reaches 0. Currently the countdown timer goes to negative seconds and the game keeps going. Currently attempt is below and any help is apricated.
public MainPage()
{
InitializeComponent();
_random = new Random(); // r is my random number generator
_countDown = 30;
SetUpMyTimers();// method for my timer
endGame();
}
private void endGame()
{
throw new NotImplementedException();
}
private void SetUpMyTimers() // calling my method
{
// start a timer to run a method every 1000ms
// that method is "TimerFunctions" that runs on the UI thread
Device.StartTimer(TimeSpan.FromMilliseconds(1000), () =>
{
Device.BeginInvokeOnMainThread(() =>
{ TimerFunctions(); });
return true;
});
}
private void TimerFunctions()
{
// change the countdown.
_countDown--;
LblCountdown.Text = _countDown.ToString();
}
The countdown is over to call the function.Use winform timer control to implement countdown function
public partial class Form1 : Form
{
TimeSpan Span = new TimeSpan(0, 0, 10);
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
Span = Span.Subtract(new TimeSpan(0, 0, 1));
label1.Text = Span.Hours.ToString() + ":" + Span.Minutes.ToString() + ":" + Span.Seconds.ToString();//时间格式0:0:10
if (Span.TotalSeconds < 0.0)//when the countdown is over
{
timer1.Enabled = false;
MessageBox.Show("game over");
}
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Interval = 1000;//Set every interval to 1 second
timer1.Enabled = true;
MessageBox.Show("End the game after 10s");
}
}
Test timer:
Hope it helps you.
You could try the following code.
<Grid>
<TextBlock Name="tbTime" />
</Grid>
Codebehind:
DispatcherTimer _timer;
TimeSpan _time;
public MainWindow()
{
InitializeComponent();
_time = TimeSpan.FromSeconds(10);
_timer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, delegate
{
tbTime.Text = _time.ToString("c");
if (_time == TimeSpan.Zero)
{
_timer.Stop();
MessageBox.Show("GameOver");
}
_time = _time.Add(TimeSpan.FromSeconds(-1));
}, Application.Current.Dispatcher);
_timer.Start();
}
The result:
I have a Windows Forms application where I need to have a timer working for 90 seconds and every second should be shown after it elapses, kind of like a stopwatch 1..2..3 etc, after 90 seconds is up, it should throw an exception that something is wrong.
I have the following code, but the RunEvent never fires.
private void ScanpXRF()
{
bool demo = false;
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
try
{
for (int timerCounter = 0; timerCounter < 90; timerCounter++)
{
timer.Interval = 1000;
timer.Tick += new EventHandler(RunEvent);
timer.Start();
if(timerCounter == 89) {
throw new Exception();
}
}
}
catch (Exception e)
{
timer.Dispose();
MessageBox.Show("There is a problem!");
}
}
private void RunEvent(object sender, System.EventArgs e)
{
//boxStatus.AppendText("RunEvent() called at " + DateTime.Now.ToLongTimeString() + "\n");
MessageBox.Show("timer fired!");
}
Is there anything I am doing wrong here or are there other suggestions for other ways to achieve the same result?
A timer needs to be declared at the form level, or else it may not be disposed of when the form closes:
System.Windows.Forms.Timer timer;
int counter = 0;
Your starting code should just start the timer:
private void ScanpXRF()
{
counter = 0;
timer = new System.Windows.Forms.Timer();
timer.Interval = 1000;
timer.Tick += RunEvent;
timer.Start();
}
The RunEvent is your Tick event being called every second, so your logic needs to go in there:
private void RunEvent(object sender, EventArgs e)
{
counter++;
if (counter >= 90) {
timer.Stop();
// do something...
}
}
made it work
private void ScanpXRF()
{
_pXRFTimerCounter = 0;
pXRFTimer.Enabled = true;
pXRFTimer.Interval = 1000;
pXRFTimer.Elapsed += new ElapsedEventHandler(pXRFTimer_Tick);
pXRFTimer.Start();
}
private static void pXRFTimer_Tick(Object sender, EventArgs e)
{
_pXRFTimerCounter++;
if (_pXRFTimerCounter >= 90)
{
pXRFTimer.Stop();
// do something...
}
else
{
MessageBox.Show(_pXRFTimerCounter.ToString() + " seconds passed");
}
}
I made the timer
System.Timers
I have application in WPF with C#.net in which we have lot of expensive operations. Recently we got this requirement: For long running processes display the busy cursor till 3 seconds, if operation is exceeding 3 second display the splash screen until operation is finished. I have searched a lot over the net but nothing seems to be relevant. Any support will be high appreciated.
We have tried something, it works but in few case it is not giving expected results. Any help would be highly appreciated.
When my internal logic display any alert message and wait for the user input, Busy Cursor function timer keep running, we got the splash too.
public class BusyCursor:IDisposable
{
private Cursor _previousCursor;
System.Timers.Timer _timer
public BusyCursor()
{
_previousCursor = Mouse.OverrideCursor;
Mouse.OverrideCursor = Cursors.Wait;
_timer = new System.Timers.Timer();
_timer.Interval = 3000;
_timer.Elapsed += timer_Tick;
_timer.Start();
}
public void timer_Tick(object sender, ElapsedEventArgs e)
{
Application.Current.Dispatcher.Invoke((new Action(() =>
{
if (!DXSplashScreen.IsActive)
{
DXSplashScreen.Show<TrippsSplashScreen>();
}
Mouse.OverrideCursor = Cursors.Arrow;
_timer.Stop();
})), DispatcherPriority.ApplicationIdle);
}
#region IDisposable Members
public void Dispose()
{
_timer.Stop();
if (DXSplashScreen.IsActive)
{
DXSplashScreen.Close();
}
Mouse.OverrideCursor = Cursors.Arrow;
}
#endregion
}
Usage:
using (new BusyCursor())
{
//logic ---
}
Thanks
bool calculating = false;
bool showingSplash = false;
void Meth(Task[] expensiveCalls)
{
Task.Factory.StartNew(() =>
{
calculating = true;
Task.Factory.StartNew(() =>
{
Task.Delay(3000).Wait();
if (calculating)
{
showingSplash = true;
//Application.Current.Dispatcher.Invoke(() => show_sphlash());
}
});
Task.WaitAll(expensiveCalls);
calculating = false;
if (showingSplash)
{
//Application.Current.Dispatcher.Invoke(() => hide_sphlash());
showingSplash = false;
}
}
);
}
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;
}));
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