I wanted to see if anyone had any experience or tips on using timers dynamically. We need a windows service that will periodically check a text file. The text file will hold a market name and a start time. The service then needs to create a timer to perform a countdown and write out countdown information to an xml file... like 23minutes
all of that works now on a windows app for one timer and one countdown...we now want to make this dynamic...
so wh开发者_StackOverflow社区en the service starts, it would create a timer for each market/countdown time... (exp Phoenix 10am, Chicago 11:45pm, etc).
Then the service would check that text file for any NEW entries... So if the file had Phoenix, Chicago and then had New York added, we would want the service to keep the Phoenix and Chicago timers running and then start a timer for New York.
im just not sure how multiple timers running under a service would interact and how the threading will work when they all need to write to the same xml file.
any thoughts on this?
im just not sure how multiple timers running under a service would interact and how the threading will work when they all need to write to the same xml file.
any thoughts on this?
It won't work well.
Timers are queued to the thread pool. The thread pool will only create a certain number of active threads at a time:
http://msdn.microsoft.com/en-us/library/0ka9477y.aspx
The number of operations that can be queued to the thread pool is limited only by available memory; however, the thread pool limits the number of threads that can be active in the process simultaneously
In addition, writing to the same file from multiple threads is going to give you bad results.
Not to mention it will be much harder to figure out what your application is doing if you have all those threads running.
A simpler approach
Take an existing timer and build your own timing system upon it that doesn't use threads.
- Create a structure defining a countdown entry.
Code:
public class Countdown
{
public DateTime Time { get; set; }
public event Action Elapsed { get; set; }
public void RaiseElasped()
{
if(Elapsed != null)
Elapsed();
}
}
Read your file, and create:
Dictionary<string, Countdown>
(name -> countdown). Put the same code in each action that you were going to put in the timers.Create a
FileSystemWatcher
to look for changes to your input file. When the file is triggered, modify the dictionary as necessary.Create a single timer with a resolution of one minute.
Every time that timer is triggered, check each item in the dictionary. If the target time has passed, call
RaiseElapsed
. (possibly remove it from the dictionary, too?)
From this point, it is hard to determine exactly what you'd want to do, because you didn't describe what gets written to a file, when it happens, how often, or what happens once your countdown has elapsed. You should be able to figure out the rest yourself, though.
The advantage of this approach is that single-threaded programs are much easier to debug, and you won't get any of the issues your question asked about (concurrent file access, or having too many threads running).
The disadvantage is that it might bog down when you have a lot of entries. But if you have a lot of entries, you should really be using a database instead of of files.
You can maintain Dictionary<string,DateTime>
that holds market name and times. At regular interval (say every minute?) you can scan through the dictionary and calculate elapsed time by simply using DateTime.Subtract() and write the result to your output file. You might also want to look at Stopwatch class.
精彩评论