-
Re: Looking to develope skills
Quote:
Originally Posted by
Dragster93
Thanks for the tip dude! :)
And I'm sorry but, I didn't mean to rush anyone into answering my question....I'm patient enough to wait for the answer.... :)
Actually, I did try searching on google but didn't get any help from there....the thing is that I couldn't find a way to generate an event for when the OK button in the FolderBrowserDialogue is clicked....
But yes, what you said is correct....I shouldn't come around asking for help for every single problem that I have.... :)
You don't need to intercept the OK button in the FolderBrowserDialog control. You just create an instance of it and call ShowDialog(). It won't return until the user presses the Ok or cancel button.
To find out whether the user clicked OK, check the DialogResult enum value:
Code:
FolderBrowserDialog dlg = newFolderBrowserDialog( );
if( DialogResult.OK == dlg.ShowDialog( ) )
{
string selectedPath = dlg.SelectedPath;
}
-
Re: Looking to develope skills
Arjay, thanks for the solution but i've already solved that problem by googling it. Now there's a problem that I can't seem to find a solution to.
How do I copy an entire directory (along with all the files) to a specific loation (selected in the folder browser dialog)??
Also, why am I not able to use the System.IO.Files or System.IO.DirectoryInfo namespaces???
Shouldn't they be installed or copied during the installation??
-
1 Attachment(s)
Re: Looking to develope skills
Ok, the File BackUp Utility is ready!! :D
And I would like someone to try it out and tell me how I can improve it.
Also, I have a small doubt.
Right now, if the Source is for eg: "d:\alarm" and the destination for eg: "d:\abhinav", the software copies only the contents of the folder 'alarm' to the destination. But what if I need the entire folder to be copied??
-
Re: Looking to develope skills
A couple of small comments:
1) With regard to code formatting, put in some white space between C# terms. It makes it easier to read with a bit of white space.
2) There's no need to call ToString() on a string property.
E.g. this,
Code:
txt_dest.Text=folderBrowserDialog2.SelectedPath.ToString();
should be
Code:
txt_dest.Text = folderBrowserDialog2.SelectedPath;
-
Re: Looking to develope skills
Quote:
Originally Posted by
Arjay
A couple of small comments:
1) With regard to code formatting, put in some white space between C# terms. It makes it easier to read with a bit of white space.
2) There's no need to call ToString() on a string property.
E.g. this,
Code:
txt_dest.Text=folderBrowserDialog2.SelectedPath.ToString();
should be
Code:
txt_dest.Text = folderBrowserDialog2.SelectedPath;
Thanks for the comments dude! :)
And thanks for that tip....will keep that in mind! ;)
So did you find a solution to my other question?? :)
-
Re: Looking to develope skills
Awright, now that the File Backup program's finally complete (ofcourse, i will be doing more modifications to it slowly slowly!), I have started making an alarm program. I constructed the code, designed the UI and even debugged it. Well, its not totally debugged! The one problem that still remains is.....hold on, its better if you read my code first....
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//The funtion that handles the calculations of the alarm
public static void SetAlarm(int hours, int minutes, int seconds)
{
string wav_loc = "c:\\testjazz.wav";
SoundPlayer spWave;
spWave = new SoundPlayer(wav_loc);
DateTime dthours = new DateTime(hours);
DateTime dtminutes = new DateTime(minutes);
DateTime dtseconds = new DateTime(seconds);
if (DateTime.Today.Hour == dthours.Hour && DateTime.Today.Minute == dtminutes.Minute && DateTime.Today.Second == dtseconds.Second)
{
spWave.Play();
}
else
{
return;
}
}
//'Set Alarm' Button
private void btn_alarm_Click(object sender, EventArgs e)
{
int hr;
int min;
int sec;
hr = int.Parse(num_hour.Value.ToString());
min = int.Parse(num_min.Value.ToString());
sec = int.Parse(num_sec.Value.ToString());
SetAlarm(hr, min, sec);
}
}
}
Everything's fine. The only problem is, whenever I click the 'Set Alarm' button (which calls "private void btn_alarm_Click(object sender, EventArgs e)"), whether the alarm time has arrived or not, the alarm starts to ring!
Can someone please explain me what's wrong with my code.
Thank You! :)
-
Re: Looking to develope skills
you're using the wrong DateTime constructor. you shold use the one that takes hours, minutes and seconds. currently it's taking ticks and I'm sure this is the buggy part.
and please use the "code" tags in your posts. you're long enough here to know that.
-
Re: Looking to develope skills
Quote:
Originally Posted by
memeloo
you're using the wrong DateTime constructor. you shold use the one that takes hours, minutes and seconds. currently it's taking ticks and I'm sure this is the buggy part.
Ohk. Thanks for clearing that doubt. :)
Btw, which constructor should I be using instead?
Quote:
Originally Posted by
memeloo
and please use the "code" tags in your posts. you're long enough here to know that.
Oops! :P
My bad. Will remember that next time. :)
-
Re: Looking to develope skills
here's the list of all constructors. try to figure it out by yourself ;]
http://msdn.microsoft.com/en-us/libr....datetime.aspx
-
Re: Looking to develope skills
Quote:
Originally Posted by
memeloo
Will do. Thanks! ;)
-
Re: Looking to develope skills
In addition to what memeloo said, you also only want to have one DateTime object (not 3).
With regard to the overuse of ToString() that I've mentioned in the past. Consider revisiing, this:
Code:
//'Set Alarm' Button
private void btn_alarm_Click(object sender, EventArgs e)
{
int hr;
int min;
int sec;
hr = int.Parse(num_hour.Value.ToString());
min = int.Parse(num_min.Value.ToString());
sec = int.Parse(num_sec.Value.ToString());
SetAlarm(hr, min, sec);
}
to this
Code:
//'Set Alarm' Button
private void btn_alarm_Click(object sender, EventArgs e)
{
SetAlarm( Convert.ToInt32( num_hour.Value )
, Convert.ToInt32( num_min.Value )
, Convert.ToInt32( num_sec.Value ) );
}
In this case, you don't really need the local hr, min, sec integer variables. Also, convert the value to a string only to parse it to an integer doesn't make much sense.
Lastly, when you post code, please use code tags (i.e [ CODE]your code here[/ CODE] minus the spaces).
-
Re: Looking to develope skills
Code:
if (DateTime.Now.Hour == dt.Hour && DateTime.Now.Minute == dt.Minute && DateTime.Now.Second == dt.Second)
{
spWave.Play();
}
I wish for this to be checked and verified at very second of the day. Could somebody please tell me what I should write in the 'for' loop???
-
Re: Looking to develope skills
I would create a helper method to do this for you. The helper method checks if the current interval has been met. If it has, it increments the next time interval and returns true; if not, it returns false.
Code:
///<summary>
/// Checks if the current time has passed the next sync time
/// If so, increments the next sync time and returns true.
///</summary>
///<param name="dtNow">Current time</param>
///<returns>True if passed next sync time; false otherwise</returns>
privatebool CheckAndIncrementNextTimeSync ( DateTime dtNow )
{
bool syncTime = false;
// Check if the current time has passed the next time
// sync time.
if ( _nextTimeSync < dtNow )
{
_nextTimeSync = dtNow.AddMinutes( _timeSyncInterval );
syncTime = true;
}
return syncTime;
}
You'll want to create a similar method and call it in a while loop and perform the action if the method returns true. For my needs, I call it as follows:
Code:
///<summary>
/// Sync the hand reader time with the PC service machine time
///</summary>
///<param name="rsiHandReader"></param>
privatevoid SyncTime( CRsiHandReader rsiHandReader )
{
DateTime dtNow = DateTime.Now;
if ( CheckAndIncrementNextTimeSync( dtNow ) )
{
RSI_TIME_DATE rsiTimeDate = new RSI_TIME_DATE( );
rsiTimeDate.year = Convert.ToByte( dtNow.Year - 2000 );
rsiTimeDate.month = Convert.ToByte( dtNow.Month );
rsiTimeDate.day = Convert.ToByte( dtNow.Day );
rsiTimeDate.hour = Convert.ToByte( dtNow.Hour );
rsiTimeDate.minute = Convert.ToByte( dtNow.Minute );
rsiTimeDate.second = Convert.ToByte( dtNow.Second );
rsiHandReader.CmdPutTime( rsiTimeDate );
Debug.WriteLine( String.Format( "SyncTime: {0}", dtNow.ToString( ) ) );
}
}
-
Re: Looking to develope skills
Could you please explain these two methods to me??? Because, I can't seem to understand either of them, though you have given the explaination in comments.
Thanks!! :)
-
Re: Looking to develope skills
From what I understand you have an alarm clock that want to play a wave file when the clock goes off. You do this by setting the alarm time to some point in the future and then check it every second.
The code I posted was from a Windows Service that sent and retrieved data to a piece of hardware (i.e. Biometric hand scanner).
In my example, the _nextTimeSync is a DateTime class field and represented the time that I should sync the time in the biometric hand scanner (i.e on my system, the biometric clock time was sync'd with the PC/Network time).
For me, I just wanted to set the next time sync on a periodic basis, so when the windows service first started, I set the next time sync to some time in the future by using DateTime.AddMinutes( ) method (this code isn't shown).
Then I simply checked the _nextTimeSync time with the current time. To help with this, I created the CheckAndIncrementNextTimeSync method which checks to see if the current time is >= the _nextTimeSync time. If it is, it increments the _nextTimeSync time based on the sync interval and returns true.
The CheckAndIncrementNextTimeSync method gets called in a loop at a fixed interval. For me, it's every 2 minutes. This is done within the SyncTime method which calls the CheckAndIncrementNextTimeSync method, if that method returns true, it sends the current pc time to the hardware.
In my opinion, the code you need is close (depending whether you want to have the alarm clock go off on a fixed interval). I would rename the _nextTimeSync field to something like _nextTimeAlarm and initially set this to the time when you want the alarm to go off.
-
Re: Looking to develope skills
Thank you very much for explaining the method to me!!! =)
I shall now show you my code and explain to you how it works. Kindly tell me whether I'm going right so far.
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Media;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//The funtion that handles the calculations of the alarm
public static void SetAlarm(int hours, int minutes, int seconds)
{
string wav_loc = "c:\\testjazz.wav";
SoundPlayer spWave;
spWave = new SoundPlayer(wav_loc);
int year, month, day;
year = int.Parse(DateTime.Now.Year.ToString());
month = int.Parse(DateTime.Now.Month.ToString());
day = int.Parse(DateTime.Now.Day.ToString());
DateTime dt = new DateTime(year, month, day, hours, minutes, seconds);
if (DateTime.Now.Hour == dt.Hour && DateTime.Now.Minute == dt.Minute && DateTime.Now.Second == dt.Second)
{
spWave.Play();
}
return;
}
//'Set Alarm' Button
private void _Click(object sender, EventArgs e)
{
SetAlarm(Convert.ToInt32(dt_time.Value.Hour), Convert.ToInt32(dt_time.Value.Minute), Convert.ToInt32(dt_time.Value.Second));
}
}
}
On the form, when the 'btn_alarm' button is clicked, it called the 'btn_alarm_Click' method. In that method, another method is called along with some passed parameters. This is the 'SetAlarm' method. This is where the entire calculation takes place.
And I think this:
Code:
if (DateTime.Now.Hour == dt.Hour && DateTime.Now.Minute == dt.Minute && DateTime.Now.Second == dt.Second)
{
spWave.Play();
}
does the work of your 'CheckandIncrementNextTimeSync' method. If not, please let me know.
Also, I wish to know, how exactly is it that I can have this 'SetAlarm' method called over and over again. I tried using an infinite loop but then the program just hangs. I understood why that was happening. It was because the loop just kept going on and on without any results! But anyways, please try and find a solution to my problem. I'm also working on different ways. Will inform you as soon as I'm done. =)
-
Re: Looking to develope skills
Dude, if you don't mind, could you help me out with another problem also?
Code:
public static bool SetAlarm(int hours, int minutes, int seconds)
{
string wav_loc = "c:\\testjazz.wav";
SoundPlayer spWave;
spWave = new SoundPlayer(wav_loc);
int year, month, day;
year = int.Parse(DateTime.Now.Year.ToString());
month = int.Parse(DateTime.Now.Month.ToString());
day = int.Parse(DateTime.Now.Day.ToString());
DateTime dt = new DateTime(year, month, day, hours, minutes, seconds);
if (DateTime.Now.Hour == dt.Hour && DateTime.Now.Minute == dt.Minute && DateTime.Now.Second == dt.Second)
{
spWave.Play();
return true;
}
}
I wish for this function to only return true or false (not anything else) but I can't seem to do that. Could you help me out?
-
Re: Looking to develope skills
Quote:
Originally Posted by
Dragster93
I wish for this function to only return true or false (not anything else)
LoL :lol: there is nothing else to return... or do you mean: true/false/maybe ? you really should read some book.
-
Re: Looking to develope skills
Quote:
Originally Posted by
memeloo
LoL :lol: there is nothing else to return... or do you mean: true/false/maybe ? you really should read some book.
Then why is it asking me to return so value for the parameters I've passed???
The exact message was, "'WindowsFormsApplication1.Form1.SetAlarm(int, int, int)': not all code paths return a value".....
-
Re: Looking to develope skills
because you return only true inside your IF and by default a function returns false. to get rid of this warning write before the method's closing brace "return false".
-
Re: Looking to develope skills
Actually, the whole point of the function is to return true (in this case). The thing is that I can't check in the 'if', whether this function has returned true or not. And the 'if' is initiated inside another function which is the 'void_Click' function (if you look at my code on top).
So....
1) How can I make the function return either true/false without having a problem with either of the parameters of the function???
2) How do I find out, in the 'void_Click' function, whether the 'SetAlarm' returned true???
-
Re: Looking to develope skills
Quote:
Originally Posted by
Dragster93
2) How do I find out, in the 'void_Click' function, whether the 'SetAlarm' returned true???
I'm sorry, but you have no idea what you're doing :sick: how do you expect a method that returns nothing (void) to return true/false? ... I give up .
-
Re: Looking to develope skills
memeloo!!!! THANK YOU!!!!! =)
You were right!!!! =)
I did what you said....and the program works!!!!! =)
Ok, now I'll explain to you how the entire program works by posting the slightly changed code that I wrote!
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Media;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//The funtion that handles the calculations of the alarm
public static bool SetAlarm(int hours, int minutes, int seconds)
{
bool check = false;
string wav_loc = "c:\\testjazz.wav";
SoundPlayer spWave;
spWave = new SoundPlayer(wav_loc);
int year, month, day;
year = int.Parse(DateTime.Now.Year.ToString());
month = int.Parse(DateTime.Now.Month.ToString());
day = int.Parse(DateTime.Now.Day.ToString());
DateTime dt = new DateTime(year, month, day, hours, minutes, seconds);
// && DateTime.Now.Second == dt.Second
if (DateTime.Now.Hour == dt.Hour && DateTime.Now.Minute == dt.Minute)
{
spWave.Play();
check = true;
}
return check;
}
//'Set Alarm' Button
private void btn_alarm_Click(object sender, EventArgs e)
{
for (int i = 1; i != 0; i++)
{
if (SetAlarm(Convert.ToInt32(dt_time.Value.Hour), Convert.ToInt32(dt_time.Value.Minute), Convert.ToInt32(dt_time.Value.Second)))
{
break;
}
}
}
}
}
Exactly what happens is, when the 'Set Alarm' button on the form is clicked, it calls the 'btn_alarm_Click' method. In this method, a FOR loop starts (which is infinite) which initiates the IF loop. In the IF loop, the condition is "If SetAlarm method returns true, then break the loop". The reason why I break the loop is so that the FOR loop will not continue to run even after the alarm time has been reached (otherwise I don't think it's gonna work). So anyways, when the 'SetAlarm' method is called, it calculates whether the current time is same as the alarm time (you can check the above code to understand how it checks). If the current time matches the alarm time, it plays a '.wav' file.
Now, right after this plays, what I had done was, I wrote "return true" in the very next line, right after the "spWave.Play()" line, which meant (like you said) it was still in the IF. So what I did was, I created a bool, set it to true, and then wrote "return bool" (which is now true) right before the moethod's closing braces (again, like you said).
Now comes the running part. It compiled and ran perfectly fine. But when I click the Set Alarm button, the program practicaly freezes (as it is stuck in the FOR loop). Is there any way to run this FOR loop in background by using the BackgroundWorker component of WinForms???
-
Re: Looking to develope skills
Your code has problems.
1) Consider the line
Code:
year = int.Parse(DateTime.Now.Year.ToString());
Remember when I told you about converting a value to a string and then parsing the string into an integer? This is a waste because DateTime.Now.Year is already an integer.
2) Calling DateTime.Now repeatedly may be problematic. You do this in several areas. Keep in mind that each time you call it, you retrieve a different 'Now' time. Typically, you call DateTime.Now once and then extract the partial time values from the one date.
Code:
DateTime dtNow = DateTime.Now;
int year = dtNow.Year;
int day = dtNow.Day;
3) The following snippet may not be reliable.
Code:
if (DateTime.Now.Hour == dt.Hour && DateTime.Now.Minute == dt.Minute)
{
spWave.Play();
check = true;
}
Just set the alarm time to the time in the future and check the whole time.
For example:
Code:
if ( dtAlarm <= DateTime.Now )
{
spWave.Play();
check = true;
}
4) Instead of the funky for loop of
Code:
for (int i = 1; i != 0; i++)
{
}
how about a while loop?
5) The UI freezes because you have an infinite loop and you are stealing all the cpu cycles. The proper way to fix this is to use a secondary thread. That way, you can disable the start button, but still retain UI control. If you don't want to use a secondary thread, you can put a Threading.Sleep( 1000 ) statement inside the while loop (but this is really a hack).
Code:
while( true )
{
if (SetAlarm( Convert.ToInt32(dt_time.Value.Hour),
Convert.ToInt32(dt_time.Value.Minute),
Convert.ToInt32(dt_time.Value.Second) ) )
{
break;
}
Threading.Sleep( 1000 );
}
6) Lastly, we really don't need your commentary on how the code works other than a few statements of what you intend the result to be.
This is because if you've done a good job writing the code, we'll be able to follow along by just reading the code. If we can't follow along,
then that indicates a problem with your code (part of the goal of writing good code is to make it so that others can easily follow it without it
requiring lengthy explaination).
we'll be able to read the code
-
Re: Looking to develope skills
Quote:
Originally Posted by
Arjay
Your code has problems.
1) Consider the line
Code:
year = int.Parse(DateTime.Now.Year.ToString());
Remember when I told you about converting a value to a string and then parsing the string into an integer? This is a waste because DateTime.Now.Year is already an integer.
I did that because otherwise, it would say, can't implicitely convert DateTime to Int.
Quote:
Originally Posted by
Arjay
2) Calling DateTime.Now repeatedly may be problematic. You do this in several areas. Keep in mind that each time you call it, you retrieve a different 'Now' time. Typically, you call DateTime.Now once and then extract the partial time values from the one date.
Code:
DateTime dtNow = DateTime.Now;
int year = dtNow.Year;
int day = dtNow.Day;
So what you're saying is that I should store the DateTime value in a variable and then use that variable rather than calling DateTime() everytime???
[/QUOTE]
Quote:
Originally Posted by
Arjay
3) The following snippet may not be reliable.
Code:
if (DateTime.Now.Hour == dt.Hour && DateTime.Now.Minute == dt.Minute)
{
spWave.Play();
check = true;
}
Just set the alarm time to the time in the future and check the whole time.
For example:
Code:
if ( dtAlarm <= DateTime.Now )
{
spWave.Play();
check = true;
}
Thanks, I shall do that. :)
Quote:
Originally Posted by
Arjay
4) Instead of the funky for loop of
Code:
for (int i = 1; i != 0; i++)
{
}
how about a while loop?
Thanks for the idea. :)
Quote:
Originally Posted by
Arjay
5) The UI freezes because you have an infinite loop and you are stealing all the cpu cycles. The proper way to fix this is to use a secondary thread. That way, you can disable the start button, but still retain UI control. If you don't want to use a secondary thread, you can put a Threading.Sleep( 1000 ) statement inside the while loop (but this is really a hack).
Code:
while( true )
{
if (SetAlarm( Convert.ToInt32(dt_time.Value.Hour),
Convert.ToInt32(dt_time.Value.Minute),
Convert.ToInt32(dt_time.Value.Second) ) )
{
break;
}
Threading.Sleep( 1000 );
}
Yes, I understood why it's freezing, that is why I tried to use the backgroundworker to do the calcuation in background. But I seem to be having a little trouble with it. I use 'backgroundworker.dispose()' to free the resources so that if the Set Alarm button is clicked a second time to set a different time, the it shouldn't display an exception saying, "The thread is busy". But that seems to work only for the second click. If you click the third time, again the same problem occurs. I shall try using the catch and throw exception for that problem and see if it works
Quote:
Originally Posted by
Arjay
6) Lastly, we really don't need your commentary on how the code works other than a few statements of what you intend the result to be.
This is because if you've done a good job writing the code, we'll be able to follow along by just reading the code. If we can't follow along,
then that indicates a problem with your code (part of the goal of writing good code is to make it so that others can easily follow it without it
requiring lengthy explaination).
we'll be able to read the code
Oops. :P
My bad. Next time onwards I shall put the comments in my code itself. :)
-
Re: Looking to develope skills
Quote:
Originally Posted by
Dragster93
I did that because otherwise, it would say, can't implicitely convert DateTime to Int.
You need to understand what DateTime.Now does. It makes an instance of the DateTime class and sets it to the current time. When you call Datetime.Now.Year, you are accessing the year property of the current date time instance. Since the Year property is declared as an integer, you don't need to convert it.
Quote:
Originally Posted by
Dragster93
So what you're saying is that I should store the DateTime value in a variable and then use that variable rather than calling DateTime() everytime???
Yes. Everytime you call DateTime.Now you are creating a separate datetime instance. Just call it once.
Quote:
Originally Posted by
Dragster93
Yes, I understood why it's freezing, that is why I tried to use the backgroundworker to do the calcuation in background. But I seem to be having a little trouble with it. I use 'backgroundworker.dispose()' to free the resources so that if the Set Alarm button is clicked a second time to set a different time, the it shouldn't display an exception saying, "The thread is busy". But that seems to work only for the second click. If you click the third time, again the same problem occurs. I shall try using the catch and throw exception for that problem and see if it works
You have something wrong with the background worker code. Post your background worker code.
-
Re: Looking to develope skills
Quote:
Originally Posted by
Arjay
You need to understand what DateTime.Now does. It makes an instance of the DateTime class and sets it to the current time. When you call Datetime.Now.Year, you are accessing the year property of the current date time instance. Since the Year property is declared as an integer, you don't need to convert it.
Now I get it! :P
Quote:
Originally Posted by
Arjay
You have something wrong with the background worker code. Post your background worker code.
Sure thing. Here it is:
Code:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int i = 0;
while (i == 0)
{
if (SetAlarm(Convert.ToInt32(dt_time.Value.Hour), Convert.ToInt32(dt_time.Value.Minute), Convert.ToInt32(dt_time.Value.Second)))
{
break;
}
}
}
And I call the backgroundworker method in this way:
Code:
private void btn_alarm_Click(object sender, EventArgs e)
{
try
{
backgroundWorker1.RunWorkerAsync();
}
catch
{
backgroundWorker1.CancelAsync();
backgroundWorker1.RunWorkerAsync();
}
}
-
Re: Looking to develope skills
With regard to checking the time. If the user specifies an hour and minute time string, I convert this to a datetime object (and merge it with the current year, month and day). Once I do this, I can do a simple datetime compare to see if the alarm should go off.
So let's say the user enters "8:00 AM" into a string variable called _wakeup. The following code takes that value, turns it into a DateTime object, merges it with the current date and then stores it in the _timeNextAlarm field.
Code:
///<summary>
/// Sets the alarm time
///</summary>
privatevoid SetInitialAlarmTime( )
{
// Parse the requested alarm time ( this arrives as std or military time, i.e. "8:00:00 AM" or "19:00:00" )
// The date time created here will have the wrong date, so we'll need to fix that up later.
DateTime requestedAlarm = DateTime.Parse( _wakeup );
// Retrieve the current date
DateTime dtNow = DateTime.Now;
// Merge the requested time with the current date.
requestedAlarm = newDateTime( dtNow.Year
, dtNow.Month
, dtNow.Day
, requestedAlarm.Hour
, requestedAlarm.Minute
, requestedAlarm.Second );
// Store the next alarm value. Check if we are already past the requested alarm time for the day.
// If we are, then increment to the next day.
_timeNextAlarm = ( requestedAlarm > dtNow )
? requestedAlarm.AddDays( 1 )
: requestedAlarm;
}
Using this strategy, it's a simple matter to reset the alarm time to the next day after the alarm goes off. All you need to do is call the AddDay( ) method on _timeNextAlarm.
-
Re: Looking to develope skills
Here's code that creates the polling thread and within the thread, checks every second to see if the alarm should sound.
Code:
// Event used to turn off the alarm (before it's been set)
privateAutoResetEvent _stopEvent = newAutoResetEvent( false );
// Alarm thread which checks every second if the alarm time
// has passed in order to trigger the alarm
privateThread _alarmThread = null;
// Wait handle array. Used to hold the stop event
privateWaitHandle [ ] _waitHandles = null;
///<summary>
/// Sets the alarm
///</summary>
publicvoid Set( )
{
Reset( );
SetInitialAlarmTime( );
CreateAlarmThread( );
}
///<summary>
/// Resets the alarm
///</summary>
publicvoid Reset( )
{
if ( null != _alarmThread )
{
// Signal the alarm thread to exit
_stopEvent.Set( );
// Close the thread reference
_alarmThread = null;
}
}
///<summary>
/// Creates and starts the alarm thread
///</summary>
privatevoid CreateAlarmThread( )
{
if ( _waitHandles == null )
{
_waitHandles = newWaitHandle [ ] { _stopEvent };
}
_alarmThread = newThread( newThreadStart( AlarmThreadProc ) );
_alarmThread.IsBackground = true;
_alarmThread.Start( );
}
///<summary>
/// Alarm thread procedure. Waits the desired time interval (1 sec)
/// before checking if the alarm should be triggered. Also
/// waits on a stop event, so the user can cancel the alarm
///</summary>
privatevoid AlarmThreadProc( )
{
while ( true )
{
switch ( WaitHandle.WaitAny( _waitHandles, 1000, false ) )
{
// Stop event signalled; exit thread
case 0:
return;
// Polling expired, check if alarm time has passed
caseWaitHandle.WaitTimeout:
if ( CheckAndIncrementNextAlarmTime( DateTime.Now ) )
{
RingAlarm( );
}
break;
}
}
}
///<summary>
/// Checks if the current time has passed the next scheduled alarm time.
/// If it has, increments the alarm time to the next day and returns true.
///</summary>
///<param name="dtNow">Current time</param>
///<returns>True to ring alarm; false otherwise</returns>
privatebool CheckAndIncrementNextAlarmTime( DateTime dtNow )
{
bool ringAlarm = false;
// Check if the current time has passed the scheduled alarm time
if ( _timeNextAlarm < dtNow )
{
_timeNextAlarm = _timeNextAlarm.AddDays( 1 );
ringAlarm = true;
}
return ringAlarm;
}
-
Re: Looking to develope skills
I'm sorry but can you explain this small snippet to me??
Code:
_timeNextAlarm = ( requestedAlarm > dtNow )
? requestedAlarm.AddDays( 1 )
: requestedAlarm;
I can't understand the syntax of this particular snippet.
And, should '_timeNextAkarm' be a DateTime object or a string???
-
Re: Looking to develope skills
Quote:
Originally Posted by
Dragster93
I'm sorry but can you explain this small snippet to me??
Code:
_timeNextAlarm = ( requestedAlarm > dtNow )
? requestedAlarm.AddDays( 1 )
: requestedAlarm;
I'm using the conditional or ternary operator.
http://msdn.microsoft.com/en-us/library/ty67wk28(VS.80).aspx
Essentially it's the same as writing:
Code:
if ( requestedAlarm > dtNow )
{
_timeNextAlarm = requestedAlarm.AddDays( 1 );
}
else
{
_timeNextAlarm = requestedAlarm;
}
Quote:
Originally Posted by
Dragster93
And, should '_timeNextAkarm' be a DateTime object or a string???
In general, for a class to be assigned to another class, the class being assigned to needs to have an assignment operator defined that is capable of converting the class doing the assigning. That means if the _timeNextAlarm object were a string, the string class would need to have an assignment operator that can take a DateTime object. The string class doesn't have any such operator defined. Therefore, _timeNextAlarm is a DateTime object. Also, you'll see in other parts of the code where I call _timeNextAlarm.AddDays( 1 ), so an AddDays( ) method would indicate that it's a DateTime object.
Tip: Deciding on the type of variable used to store and pass around is a very important programming consideration. Many beginning programmers [over] use strings to store data, where they really should be using a data type that more closely matches what they are storing.
For example, you can store the age of a person in a string, but you probably would want to use a different type like an integer because you can't perform math operations on a string. If I want to averages the ages for a list of persons and the ages are stored as strings, then I'm going to need to convert the string to integers first. If you choose your type carefully, then you end up with the least amount of conversions.
I chose the DateTime type because I now have all the methods and properties of a DateTime type at my disposal (such as the AddDays( 1 )). Had I stored the DateTime as a string, then a simple operation such as Adding a day to the current datetime would be a major undertaking for me to have to code up because I would have to account for end of month, end of year, and other special cases. By using the proper DateTime type, adding a day to the current day is a simple method call (and the DateTime class handles the complexity under the covers).
-
Re: Looking to develope skills
Quote:
Originally Posted by
Arjay
I'm using the conditional or ternary operator.
http://msdn.microsoft.com/en-us/library/ty67wk28(VS.80).aspx
Essentially it's the same as writing:
Code:
if ( requestedAlarm > dtNow )
{
_timeNextAlarm = requestedAlarm.AddDays( 1 );
}
else
{
_timeNextAlarm = requestedAlarm;
}
In general, for a class to be assigned to another class, the class being assigned to needs to have an assignment operator defined that is capable of converting the class doing the assigning. That means if the _timeNextAlarm object were a string, the string class would need to have an assignment operator that can take a DateTime object. The string class doesn't have any such operator defined. Therefore, _timeNextAlarm is a DateTime object. Also, you'll see in other parts of the code where I call _timeNextAlarm.AddDays( 1 ), so an AddDays( ) method would indicate that it's a DateTime object.
Tip: Deciding on the type of variable used to store and pass around is a very important programming consideration. Many beginning programmers [over] use strings to store data, where they really should be using a data type that more closely matches what they are storing.
For example, you can store the age of a person in a string, but you probably would want to use a different type like an integer because you can't perform math operations on a string. If I want to averages the ages for a list of persons and the ages are stored as strings, then I'm going to need to convert the string to integers first. If you choose your type carefully, then you end up with the least amount of conversions.
I chose the DateTime type because I now have all the methods and properties of a DateTime type at my disposal (such as the AddDays( 1 )). Had I stored the DateTime as a string, then a simple operation such as Adding a day to the current datetime would be a major undertaking for me to have to code up because I would have to account for end of month, end of year, and other special cases. By using the proper DateTime type, adding a day to the current day is a simple method call (and the DateTime class handles the complexity under the covers).
Thank You so much for explaining that to me! =)
It really helped! =)
-
Re: Looking to develope skills
I'm sorry but this is gonna sound a lil stupid!
Your ? condition says
Code:
_timeNextAlarm = ( requestedAlarm > dtNow )
? requestedAlarm.AddDays( 1 )
: requestedAlarm;
it the 'requestedAlarm' time is more than 'dtNow' time, that means the time is yet to come... then why would we add another day to it?
-
Re: Looking to develope skills
Quote:
Originally Posted by
Dragster93
I'm sorry but this is gonna sound a lil stupid!
Your ? condition says
Code:
_timeNextAlarm = ( requestedAlarm > dtNow )
? requestedAlarm.AddDays( 1 )
: requestedAlarm;
it the 'requestedAlarm' time is more than 'dtNow' time, that means the time is yet to come... then why would we add another day to it?
That would be a bug. It should be.
Code:
_timeNextAlarm = ( requestedAlarm < dtNow )
? requestedAlarm.AddDays( 1 )
: requestedAlarm;
-
Re: Looking to develope skills
Also, I couldn't understand this SWITCH:
Code:
while ( true )
{
switch ( WaitHandle.WaitAny( _waitHandles, 1000, false ) )
{
// Stop event signalled; exit thread
case 0:
return;
// Polling expired, check if alarm time has passed
caseWaitHandle.WaitTimeout:
if ( CheckAndIncrementNextAlarmTime( DateTime.Now ) )
{
RingAlarm( );
}
break;
}
}
I've worked with switch cases before but it was usually between a choice of numbers like 1-9 or something like that. Could you explain this to me?
And, WHILE (which object returns TRUE)?
-
Re: Looking to develope skills
Quote:
Originally Posted by
Dragster93
Also, I couldn't understand this SWITCH:
Code:
while ( true )
{
switch ( WaitHandle.WaitAny( _waitHandles, 1000, false ) )
{
// Stop event signalled; exit thread
case 0:
return;
// Polling expired, check if alarm time has passed
caseWaitHandle.WaitTimeout:
if ( CheckAndIncrementNextAlarmTime( DateTime.Now ) )
{
RingAlarm( );
}
break;
}
}
I've worked with switch cases before but it was usually between a choice of numbers like 1-9 or something like that. Could you explain this to me?
And, WHILE (which object returns TRUE)?
A switch statement does act on numbers (and other types) and I'm waiting on two numbers. I'm waiting on 0, which is the index to the stop event object specified in the wait handle array and on WaitHandle.WaitTimeout which is defined as 258. To help understand this, look in Msdn for WaitHandle.WaitAny. It will explain the method and it's the return values. Essentially, I use this function as a timer function. Waiting on the stop event allows me to signal the thread to exit (which is a clean way of getting a thread to exit). I specify a timeout value, so that WaitAny returns on the timeout which I use to check if the alarm should be sounded.
while( true ) just means to loop indefinitely. We want to do this because we'll be checking whether to ring the alarm on the timeout and only want to exit the loop (and the thread) if the stop event is called.
Keep in mind that this approach is roughly equivalent to:
Code:
while ( true )
{
if( WaitHandle.WaitAny( _waitHandles ) == 0 )
{
// Stop event signalled; exit thread
return;
}
if ( CheckAndIncrementNextAlarmTime( DateTime.Now ) )
{
RingAlarm( );
}
Threading.Sleep( timeout );
}
However, the switch approach yields more immediate response as the timeout value get longer. In other words, if I'm trying the exit the thread by setting the stop event and have a timeout of 2 minutes, I may have to wait up to two minutes for the thread to exit. This is because I could be sitting in the Sleep( ) method before I get back around to checking if the stop event has been set.
With the switch statement, the response time isn't dependent on the timeout time because the WaitAny method does the waiting for you and will return immediately when the stop event has been set (regardless of whether the timeout has expired).
One major distinction of this code over your original code is that this code essentially puts the thread to sleep while waiting (which is extremely important). Your original code simply spun and kept calling your check method. Had your code been run, you would have noticed that the cpu usage would have gone through the roof.
-
Re: Looking to develope skills
Thank you for explaining that! =)
Ok, I've typed down the coding as per to what all you told me to type. It runs fine. Only thing is, if the time is set to a time in the future (like it should be) the alarm (which is a MessageBox) keeps getting triggered every second, whether the time has been reached.....OR NOT!!!
This is what my code looks like:
Code:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private AutoResetEvent stopThread = new AutoResetEvent(false);
private Thread alarmThread = null;
private WaitHandle[] waitHandles = null;
private void btn_setalarm_Click(object sender, EventArgs e)
{
Reset();
CreateAlarmThread();
}
private void Reset()
{
if (null != alarmThread)
{
//Signaling the stopThread
stopThread.Set();
//Close thread referrence
alarmThread = null;
}
}
private void AlarmThreadProcedure()
{
while (true)
{
switch(WaitHandle.WaitAny(waitHandles,1000,false))
{
//Stop event signalled. Exit thread.
case 0:
return;
//Polling thread expired. Check if alarm time has passed.
case WaitHandle.WaitTimeout:
if (CheckAndIncrementNextAlarmTime())
{
MessageBox.Show("Alarm");
}
break;
}
}
}
private void CreateAlarmThread()
{
if (waitHandles == null)
{
waitHandles = new WaitHandle[] { stopThread };
}
alarmThread = new Thread(new ThreadStart(AlarmThreadProcedure));
alarmThread.IsBackground = true;
alarmThread.Start();
}
private bool CheckAndIncrementNextAlarmTime()
{
bool ringAlarm=false;
//Time selected by the user
DateTime setAlarm = DateTime.Parse(dt_alarm.Value.ToString());
//Current time
DateTime dt_now = DateTime.Now;
//Merge the 'selected' and 'current' times
setAlarm = new DateTime(dt_now.Year
, dt_now.Month
, dt_now.Day
, setAlarm.Hour
, setAlarm.Minute
, setAlarm.Second);
//Store the next time value. If date has already been passed, increment next day.
DateTime timeNextAlarm = new DateTime();
if (setAlarm < dt_now)
{
timeNextAlarm = setAlarm.AddDays(1);
}
else
{
timeNextAlarm = setAlarm;
ringAlarm = true;
}
return ringAlarm;
}
}
}
I know it's me who has done something wrong but I just can't seem to find the bug! I read the code several times, but still nothing. When you're free, could you just have a look at my code?
-
Re: Looking to develope skills
You didn't copy the code as I typed it. Take another look at the code in my responses of #78 and #79. I have an InitializeAlarmTime( ) method which you need to call in your SetAlarm button handler:
Code:
private void btn_setalarm_Click(object sender, EventArgs e)
{
Reset();
SetInitialAlarmTime( );
CreateAlarmThread( );
}
Then compare your CheckAndIncrementNextAlarmTime( ) method with mine. You'll see that mine is simpler and that you've merged the functionality of SetInitialAlarmTime( ) with CheckAndIncrementNextAlarmTime( ).
All the check method should do is check to see if the alarm time has passed. If it has, it sets the day to the next and returns true. Your check method keeps initializing the time from your text box. It shouldn't do this.
Btw, if you aren't doing so, you need to start using the debugger. You can set a breakpoint in the while( true ) loop by pressing F9. Then each time through the loop, you can check the values _nextTimeAlarm and other values. This will help you figure out what is going wrong.
-
Re: Looking to develope skills
Dragster93 !
To be a good programmer you should have a good grip on algorithms. Do you know what an algorithm is !
Secondly, after reading all the replies I have come to the conclusion that your basic programming skills are not well developed yet, and you are trying to go for big things. You should buy some beginner level C# programming book and read it thoroughly and solve the given exercises at the end of each chapter.
Although the work you are doing with the help of forum members is not bad at all, but you should know the basic syntax of any certain language to be able to code in it.
in the meantime, let me think some other advice for you...
-
Re: Looking to develope skills
-
Re: Looking to develope skills
Quote:
Originally Posted by
Arjay
You didn't copy the code as I typed it. Take another look at the code in my responses of #78 and #79. I have an InitializeAlarmTime( ) method which you need to call in your SetAlarm button handler:
Code:
private void btn_setalarm_Click(object sender, EventArgs e)
{
Reset();
SetInitialAlarmTime( );
CreateAlarmThread( );
}
Then compare your CheckAndIncrementNextAlarmTime( ) method with mine. You'll see that mine is simpler and that you've merged the functionality of SetInitialAlarmTime( ) with CheckAndIncrementNextAlarmTime( ).
All the check method should do is check to see if the alarm time has passed. If it has, it sets the day to the next and returns true. Your check method keeps initializing the time from your text box. It shouldn't do this.
Btw, if you aren't doing so, you need to start using the debugger. You can set a breakpoint in the while( true ) loop by pressing F9. Then each time through the loop, you can check the values _nextTimeAlarm and other values. This will help you figure out what is going wrong.
Oh yes! My bad!
I shall make the necessary changes, study the program thoroughly once more, understand what's goin on by setting the breakpoints, and then get back to you.
And thanks for the tip on using the debugger! :)
Quote:
Originally Posted by
nabeelisnabeel
Dragster93 !
To be a good programmer you should have a good grip on algorithms. Do you know what an algorithm is !
Secondly, after reading all the replies I have come to the conclusion that your basic programming skills are not well developed yet, and you are trying to go for big things. You should buy some beginner level C# programming book and read it thoroughly and solve the given exercises at the end of each chapter.
Although the work you are doing with the help of forum members is not bad at all, but you should know the basic syntax of any certain language to be able to code in it.
in the meantime, let me think some other advice for you...
Yes, I'm familiar the concept of algorithms.....never got a chance a chance to study it though....
I do have basic knowledge about the syntax, but like you said, my skills are not well developed yet. And as you know, the language is very vast, so it not so easy to know every thing about the language so fast. My main objective of doing such projects is to develope my skills. I do have 2 books already :
1) C# (which is basically for Console Apps)
2) WinForms with C# (which cannot be studied if you haven't read no.1)
And you are VERY right about the fact that I should read some books and do the given exercise to so I can get the syntax and the basics of the language! :)
I shall do that. But in the mean time I would like to continue making these small programs also.
Quote:
Originally Posted by
nabeelisnabeel
Yes, I read the post. You know what. I think I'll help the guy out. Because, I know how to make databases work with C#.
It'll be like another challenge! :)
I shall start on his program once I'm done with my Alarm program.