So I'm using the Kinect SDK to make an application, and it's going well! I'm trying to make a button take a picture, but I want the code taking the picture to be delayed so the people have time to pose. I've tried using System.Threading.Thread.Sleep(3000); but what happens is that the whole thing freezes (Yes I know that's what sleep does...) and it uses the first frame anyway. So now I'm trying to use a Timer and Timed Event, but keep getting errors due to the inability to make it static (Kinect thing).
public class Timer1
{
private System.Timers.Timer aTimer;
public void Main()
{
aTimer = new System.Timers.Timer(3000);
//This is where the problem is. I'm getting "Cannot access a non-static member of outer type 'KinectButton.MainWindow' via nested type 'KinectButton.MainWindow.Timer1'
aTimer.Elapsed += new ElapsedEventHandler(takepicture);
aTimer.Interval = 1000;
aTimer.Enabled = True;
}
}
[private void takepicture(object sender, ElapsedEventArgs e)
{
BitmapSource image = (BitmapSource)videoStream.Source;
image.Save(DateTime.Now.ToString("ddMMyyyy HHmmss") + ".jpg", ImageFormat.Jpeg);
}
private void button7_Click(object sender, RoutedEventArgs e)
{
//Here I'm also getting "'KinectButton.MainWindow.Timer1' does not contain a definition for 'Enabled'"
Timer1.Enabled = true;
}
private void Timer1_Tick(object sender, EventArgs e)
{
//Here I'm getting "'KinectButton.MainWindow.Timer1' does not contain a definition for 'Enabled'" again...
Timer1.Enabled = false;
}
Well, let me know if you guys can help!
I assume this is a WPF app? I think you will want to use Windows.Threading.DispatcherTimer instead
Private timer As New Windows.Threading.DispatcherTimer
timer.Interval = New TimeSpan(0, 0, 0, 1)
AddHandler timer.Tick, AddressOf timer_Tick
timer.Start()
Private Sub timer_Tick(ByVal Sender As Object, ByVal e As EventArgs)
'do something
End Sub
yeah i know its vb but it should be easy to convert
Related
i´m doing a winform app, and the timer isn´t working fine. First time works, and then, it doesn´t.
Here is the code:
public void GetNewTurn(Turn turn)
{
_tmrStarTime = DateTime.Now;
timer1.Start();
timer1.Tick += tmr1_Tick;
}
private void tmr1_Tick(object sender, EventArgs e)
{
//timer code here
timer.stop();
}
So, the idea is:
GetNewTurn is a function which is invoked from another place. The first time which I invoke it, works fine, then doesn´t. I put a breakpoint inside the tmr1_Tick, and i can see that it just works the first time, then, doesn´t.
In the Timer properties, i set Enable = True.
What i´m doing wrong?
Thanks!
You shoudn't stop the tmr1_Tick in the first tick
public void GetNewTurn(Turn turn)
{
_tmrStarTime = DateTime.Now;
timer1.Start();
timer1.Tick += tmr1_Tick;
}
private void tmr1_Tick(object sender, EventArgs e)
{
//the code for each tick
}
Only add the handler once in the constructor or OnLoad override.
timer1.Tick += tmr1_Tick;
public void GetNewTurn(Turn turn)
{
_tmrStarTime = DateTime.Now;
timer1.Start();
}
Basically, I have a frequency that refreshes data on screen. When one of these data points goes over a set value, it sets off an error. Upon this error setting off, I want the background colour to change (like a flashing warning).
The problem I have is that I am already using a timer, and when I call a new timer (for the flash) it stops the other timer working, and I'm unaware of how to call in the previous method (being as it uses object sender)
Here is my code:
public void Freq_Change(object sender, SelectionChangedEventArgs e)
{
_timer.Stop();
_timer.Interval = TimeSpan.FromSeconds(Freq.SelectedIndex + 1);
_timer.Start();
_timer.Tick += timer_Tick;
}
and timer_Tick
void timer_Tick(object sender, EventArgs e)
{
//Data generator
//Value pushes to text boxes
if (value is over 100)
{
Warning_Blink
"Oh no, an error"
}
else
{
"All good"
}
Warning_Blink has the new timer in, which then calls warning_Tick
In warning_Tick
private bool _warning = false;
private void warning_Tick(object sender, EventArgs e)
{
if (_warning)
{
ErrorBox.Background = new SolidColorBrush(Colors.Red);
}
else
{
ErrorBox.Background = new SolidColorBrush(Colors.White);
}
_warning = !_warning;
Freq_Change();
}
Here where I call Freq_Change (which doesn't work) I want to be able to go back to the old timer (or better yet never switch between the two) so the data generation can continue.
Can anyone help me with this? I've been scratching my head for hours
I'm trying to make a timer run in a textbox and I haven't had any luck.
This is the code I'm using:
private static System.Timers.Timer timer;
...
private void StartBtn_Click(object sender, EventArgs e)
{
timer = new System.Timers.Timer(1000);
timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
timer.Enabled = true;
}
...
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
TimeTb.Text = e.SignalTime.ToString();
}
But nothing happens.
I tried this:
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
MessageBox.Show(e.SignalTime.ToString(),
"Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
}
And it worked fine. Anyone know why it isn't working with my textbox?
The Elapsed Event runs on a different Thread then the UI. Its not allowed to manipulate UI Objects from a different thread and an Exception should surface in your EventHandler. Since you don't handle Exceptions there you won't notice it.
In StartBtn_Click set the SynchronizingObject Property of the Timer to this (the form). Then the elapsed Event will be synchronized with the main thread.
May be you should start the timer first.
Take a look at:
http://msdn.microsoft.com/en-us/library/system.timers.timer.start.aspx
So add:
timer.Start();
Put a try catch around OnTimedEvent and see if there are any issues with threading.
If there are, try using the System.Windows.Forms.Timer which can resolve the issues of cross threading.
http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx
As stated:
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.
Your OnTimedEvent callback will not be called on the UI thread, so you will get an exception in there trying to set the textbox text. So you need to change the event handler to look like this:
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
if (TimeTb.InvokeRequired)
{
TimeTb.Invoke((MethodInvoker)delegate
{
OnTimedEvent(source, e);
});
}
TimeTb.Text = e.SignalTime.ToString();
}
Maybe using Application.DoEvents(); after TimeTb.Text = e.SignalTime.ToString(); would work, though using it would not be recommended (Use of Application.DoEvents()).
you could do something like
private void Button_Click(object sender, RoutedEventArgs e)
{
this._timer = new DispatcherTimer();
this._timer.Interval = TimeSpan.FromMilliseconds(1);
this._timer.Tick += new EventHandler(_timer_Tick);
_timer.Start();
}
void _timer_Tick(object sender, EventArgs e)
{
t= t.Add(TimeSpan.FromMilliseconds(1));
textBox.Text = t.Hours + ":" + t.Minutes + ":" + t.Seconds + ":" + t.Milliseconds;
}
Edit :
How to add Assembly: WindowsBase
I have been looking for a reason, but about every single topic on stackoverflow I could find suggested a busy UI as the reason.
I have very basic code, just for testings and it simply won't update the UI, even though I am sure it cannot be busy doing something else:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
static double t = 0;
static double dt = 0.1;
private void button1_Click(object sender, RoutedEventArgs e)
{
Timer timer = new Timer(5000);
timer.Enabled = true;
timer.Elapsed += new ElapsedEventHandler(Update);
timer.Start();
}
void Update(object sender, ElapsedEventArgs e)
{
t = t + dt;
testBlock1.Text = (t).ToString();
}
}
I debugged it and set a breakpoint to the textBlock1.Text update and it did break every 5 seconds, but the UI is never updated. As can be seen in the code, when I move my mouse over the Button I use to start the timer, the button shows its typical "mouse-over-button" animation. Why does that happen, but not the text update?
If anyone can lead me to a good topic on stackoverflow, please do so and I will delete my question here, but I couldn't find any topic explaining why this approach doesn't update the UI even though the UI is not busy doing anyting else.
System.Timers.Timer won't by default marshal back to the UI thread. In Windows Forms you can make it do so easily enough:
Timer timer = new Timer(5000);
timer.SynchronizingObject = this;
... but WPF UI elements don't implement ISynchronizeInvoke, which would stop this from working for you in WPF.
You could use the Dispatcher to marshal over to the UI thread within the handler, or you could just use a DispatcherTimer to start with.
For WPF, you should use DispatcherTimer -
Also with the above code you posted, i am getting a cross thread error since elapsed event is raised on other thread and not on UI thread.
private void button1_Click(object sender, RoutedEventArgs e)
{
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 5);
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
t = t + dt;
txt.Text = (t + dt).ToString();
}
EDIT
Also, you can marshal it on UI Dispatcher with your existing code like this -
void Update(object sender, ElapsedEventArgs e)
{
App.Current.Dispatcher.Invoke((Action)delegate()
{
t = t + dt;
txt.Text = (t + dt).ToString();
});
}
The Timer following is System.Windows.Forms.Timer
C# Code:
Timer myTimer = new Timer();
myTimer.Interval = 10000;
myTimer.Tick += new EventHandler(doSth);
myTimer.Start();
The timer will doSth every 10 seconds, but how to let it doSth immediately when starting?
I tried to create a custom timer which extends Timer, but I can't override the Start method.
For now, my code is:
myTimer.Start();
doSth(this, null);
I don't think it's good. How to improve it?
It's perfect. Don't change a thing.
I'm not sure of your exact requirements but why not put the code inside your timer callback inside another method?
e.g.
private void tmrOneSec_Tick(object sender, System.EventArgs e)
{
DoTimerStuff();
}
private void DoTimerStuff()
{
//put the code that was in your timer callback here
}
So that way you can just call DoTimerStuff() when your application starts up.
The timer has to have form level scope, and it's not clear that you have that. I whipped up a small example out of curiosity and it is working for me:
private void Form1_Load(object sender, EventArgs e)
{
txtLookup.Text = "test";
DoSomething();
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
DoSomething();
}
private void DoSomething()
{
txtLookup.Text += "ticking";
}
Every 10 seconds it appends another "ticking" to the text in the textbox.
You say,
"The timer will doSth every 10 seconds, but how to let it doSth immediately when starting?"
I say, call doSth immediately before calling the timer's start method