|
then use a timer; however don't rely on exact timing, you might miss a start if the system happens to be busy.
Instead use a time window, and check the current date is different from the date it ran last.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Make sure you handle the case where the machine may be rebooted or your service restarted, even during the reporting time window.
|
|
|
|
|
This seems the most simple way... basically set the windows scheduler to run the application at certain times. I like it... I will give it a try
|
|
|
|
|
Use a timer.
1- Calculate the amount of time until 7am.
2- Set a timer to wake you up when that amount of time has passed.
3- When the timer wakes you up, do your stuff.
4- Goto 1.
Go with D@nish's suggestion, much better.
|
|
|
|
|
Firstly - I'd set up some method by which each report can be scheduled to be run and/or sent at a different time (because that's bound to be a requirement in the future!)
Get your collection of scheduled times and convert them to 'next run Date Times' sorted in ascending order. Remember you will need some way of telling when a report was last run, too, so that a report scheduled for 7:00 does not also get run at 7:01)
Calculate teh time from NOW to the first entry in your list. Set a timer for this duration (less a short amount to cater for discrepancies.
Decide whether you will allow new reports to be added into the current schedule between NOW and the next scheduled report time, or reports to be removed from the schedule. (if you do, you need some polling to detect a change, and restart the algorithm .
On 'waking' re-build the collection (in case something has changed). If the next scheduled report is due (or past due) run it, and update it's 'Last Run' date/time then re-create the collection (catch multiple reports scheduled simultaneously).
You need to decide (assuming you implement the polling mentioned above) how time critical you need it to be. If +- 5 minutes is going to be OK - then your polling can be once every five minutes (remembering that your polling should probably be paused while any report is in progress)
Hint for young players; When I had somethinglike this implemented a few years ago, the developer created the list of reportsw by selecting WHERE ScheduledTime > TimeRightNow - this doesn't work if the time the report is scheduled for has passed (because, for example, teh previous report took a long time to run) - you need to include rpeorts based on whether the report has been run for the last scheduled time, not whether that time has passed.
___________________________________________
.\\axxx
(That's an 'M')
|
|
|
|
|
Maxxx,
Thats for your advice. Although I think that is getting a little too complex for me right now. Maybe its late.. I dunno.
I think right now.. the easiest solution for me is the console application. Although I much rather do a Windows Service so I can learn to use it more, I will try this right now...
Maybe if I had a close example of your suggestion.. like an article or something I could read to better understand how exactly you see it working.
|
|
|
|
|
What if I did this?
There is only one email I want to send at (or around) 7 am on Monday mornings.
So what if i set a boolean to false
private bool Ran = false;
Then on timer tick (every 2 minutes)
private void timerReport_Tick(object sender, EventArgs e)
{
if (DateTime.Today.DayOfWeek == DayOfWeek.Monday)
{
if (!Ran)
{
PrepareReport();
Ran = true;
}
}
else Ran = false;
}
Basically every time the timer ticks and the day isn't Monday, it says Ran to false. Meaning that it hasnt Ran.
So if the day IS Monday and the boolean is FALSE, then it prepares and sends the report, then sets RAN to true.
So RAN wouldn't get set to FALSE until the day isn't Monday...
What do you guys think about this?
Waste of resources?
|
|
|
|
|
That would run your report at 00:02 (or there abouts) on monday and, if you don't persist the 'ran' status somehow, won't work if the program is stopped for any reason (if it is restarted on a Monday you would always get another copy of the report).
Maybe..
timer.Stop();
if (!ran && DateTime.Today.DayOfWeek == dayToRun && DateTime.Now.TimeOfDay >= timeToRun)
{
PrepareReport();
ran = true;
}
timer.Interval = MillisecondsBeforeTimeToRun();
ran = false;
timer.Start();
Then you write MillisecondsBeforeTimeToRun() to calculate how long between now and the next time you want to test for the report being run.
Simplest case - if today is report day and the report has not been run, it's the difference between the time right now and the report time.
If the day is report day and the report has been run, it's 6 days from now plus the number of minutes until midnight from now, plus the report time.
If the day is not report day, you can safely leave it for (24 - now) + report time before checking again (or you can work it out accurately)
All this is obviously a bit pedantic - if you are just running one report once a week - I mean, the overheads of the polling every 2 mins are nothing - but it's nice to do these things 'properly'
___________________________________________
.\\axxx
(That's an 'M')
|
|
|
|
|
Hi there,
c#/.net n00b
I have an application that consists only of a NotifyIcon and a ContextMenu (not a menu strip) and I want to be able to "pop" the context menu to a particular option without mouse interaction. Is this possible?
The reason I want to do this is in my context menu I have a list of items that the user can choose to refresh, I'd like the context menu to pop back to the list of items after the refresh.
When I try to use the Show method it wants a Control and a Point.
Many thanks in advance!
|
|
|
|
|
I have been thinking about this... Having a submenu works well because I can capture the Popup event and refresh the contents before it is displayed. However I'd still like to make a refresh item that doesn't close the context menu. Or one that pops the menu back to where it was before.
Anyone have any ideas?
|
|
|
|
|
Solved: I realized I'm a huge dummy and forgot a transaction I wrapped around delete operation. Turns out I forgot to add a trans.Complete() at the end of it. I added it and problem solved.
I have a typed DataSet mapping a local SQL Server CE 3.5 .sdf file using DataGridView on a WinForm. I can successfully add and modify data but for some reason I can't delete any. I don't get any errors either. Can you please give me any ideas about what could be wrong? I can't figure this out and I'd appreciate any help.
I use simple methods like this:
fill
myTableTableAdapter.Fill(myDataSet.MyTable);
add
(after adding new row to grid also to bindingsource)
myTableTableAdapter.Update(myDataSet.MyTable);
delete
myDataSet.MyTableRow row = myDataSet.MyTable.FindByID(id);
row.Delete();
myTableTableAdapter.Update(myDataSet.MyTable);
The row is gone from gridview. I also check myDataSet.MyTable parameter in myTableTableAdapter.Update(myDataSet.MyTable) using debug visualizer, it's is gone from there too (row status: Deleted). But when I refill data from database, it's back like nothing happend..
I checked DeleteCommand of the myTableTableAdapter, it is defined and correct.
I don't copy project database file over the newer build file either.
I wrote a simple log to see the rowstatus of the row. Everything seems to work as it should but still the row comes back after a db refill:
Log: row status: Unchanged
Log: calling row.Delete()
Log: row status: Deleted
Log: entering Update() function
Log: row status: Deleted
Log: calling tableAdapter.Update(dataset.Table)
Log: row status: row not found in dataset
Any ideas?
modified on Tuesday, May 26, 2009 6:12 AM
|
|
|
|
|
Does the delete work in T-SQL?
|
|
|
|
|
Yes I can delete with sql. I added a query to table adapter and I can delete records using it. However I'm trying to create a fully disconnected application so I really would like to solve this delete problem.
Any ideas?
|
|
|
|
|
Alright, problem solved. I realized I'm a huge dummy and forgot a transaction I wrapped around delete operation. Turns out I forgot to add a trans.Complete() at the end of it. I added it and problem solved.
|
|
|
|
|
Hi,
I am wanting to learn a little about how a program saves data ie saved files for a game or a program. Is there a link anyone can recommend so I can learn how to create a professional file type that i can use in my program?
I also have a program linguata that i am using to learn a foreign language. The way the program works is that it has a basic file structure and for each different language it has an ogg file (containing all the sound data) and another "lesson" file that has the word/phrase in english and the other language. it also has the specific time that the word/phrase appears in the ogg file. I want to be able to de-construct the "lesson" file so i can get the raw data for the program. with this i want to create word games to help me learn.
the file is located http://rapidshare.com/files/237060596/lesson[^]
is it possible to read it in anyway or is it encrypted?
thanks
|
|
|
|
|
Hi I like file types (yea I know that's strange, but really, I do) and in particular, decoding unknown file types. So therefore I will break the rule of not downloading strange files and dive right in.
This file doesn't look encrypted, so that's good.
And I'm using XVI32 to open it, btw. I suppose there are better hex editors but I kinda grew up with it..
So, the structure. After a little header (which only seems to contain a version number) there comes a big part of 64byte structs. I can't really say much about them without having a second file of the same type to compare it with though.
But there are some things I can say. It definitely starts with an int, but I can't say what it means (could be a pointer to a record somewhere in an other section of the file). At first it seems to be rising, but that quickly stops. Then an other int, which is usually zero. Then an other int, which does seem to consistently rise (could be the time in the ogg file? a pointer into one of the records in an other section of the file?). Then just a bunch of zero's and the language name, it seems.
Then after a whole bunch of zero's, there are pairs of words + translation. Looks like 16bit unicode. The records seem to have a fixed length of 164 bytes (so 82 chars, but most of them are \0)
More zero's.. (do they waste space on purpose or what?)
Then some untranslated words? strange
More zero's..
Some rising numbers? Fun, I guess. Don't know what they do.
More zero's..
It ends with some data that doesn't look particularly useful..
And a footer ": MMG " (possibly without the ":")
It could turn out to be completely different of course.
|
|
|
|
|
GREAT! Thanks
Two Questions though:
first. ok so now I can see a readable version of the data how do i get access to it? how can I read it with C#?
and second. The first bit of my original question. How do i make a file type myself. I have been using BinaryReader and giving the file the extension I like but it is easy to view the file again in paint. I want my filetype to be professional so it really shouldnt I shouldnt be able to read it in paint. Do you know of a link with an example project?
Any ideas
|
|
|
|
|
I would read it with a BinaryReader
What do you mean in paint? MS paint? You can trick it to load an exe if you wanted..
The structure of this file was not especially "professional", in fact, it just sucks. Sure it gets the job done - it saves the data. But file structures for Real Programmers contain funny data structures - heaps, trees, length-prefixed blocks, whatever you want except fixed length strings (they just waste space).
There has also been a growing trend towards splitting your data in logical parts (if there is more than 1), zipping them all together, but giving it a custom extension (not .zip). Even .docx and .odt work this way. As a bonus it compresses your data so you can make the most ridiculously space wasting format you want and get away with it.
"Nice" formats to look at to get an idea are (for example) png and bzip2
|
|
|
|
|
sorry I meant c# not paint. dont know why i wrote that!
Can you give me an idea how I can read the data with C#? or is there a way to output to a format that I can use with c#?
Regarding the other question. I have a simple datatable that I want to save to a file. How should I do this.
Thanks for the help.
|
|
|
|
|
1) use BinaryReader
2) use BinaryWriter
|
|
|
|
|
i am trying to with the following code:
OpenFileDialog fd = new OpenFileDialog();
if (fd.ShowDialog() == DialogResult.OK)
{
FileStream streamR = new FileStream(fd.FileName, FileMode.Open);
BinaryReader r = new BinaryReader(streamR);
int count=0;
while (true)
{string st=r.ReadString();
if ((count > 374855)&&(st != string.Empty))
MessageBox.Show(count+"|"+st+"|");
count++;
}
}
I am not getting anything i can read. Any ideas?
|
|
|
|
|
ReadString expects a crazy string format that no one uses except WriteString in BinaryWriter
You could read a byte array and use Encoding.UTF16.GetString(bytes) or something like that
|
|
|
|
|
ok still no luck I tried the code below:
OpenFileDialog fd = new OpenFileDialog();
if (fd.ShowDialog() == DialogResult.OK)
{
// fd.FileName;
//
FileStream streamR = new FileStream(fd.FileName, FileMode.Open);
BinaryReader r = new BinaryReader(streamR);
int count=0;
while (true)
{byte[] st=r.ReadBytes(8);
if ((count > 374855) && (Encoding.UTF8.GetString(st)!=string.Empty))
MessageBox.Show(count + "|" + Encoding.UTF8.GetString(st) + "|");
count++;
}
}
I used UTF8 because there wasnt a UTF16.
|
|
|
|
|
Hm.. try Encoding.Unicode ?
|
|
|
|
|
no that doesnt work either.
is this correct in my code?
byte[] st=r.ReadBytes(8);
|
|
|
|