I am wondering where can I find some sample code to do this in C#:
A BackGroundWorker periodically (say, 4 times per second) checking a .txt file to see it one particular string, such as "I am done." get written in the file.
Once the BackGroundWorker finds such a string exist in the .txt, it should trigger a event becoming true.
I am a newbie for C#, so some sample would be highly appreciated. Thanks a lot.
There are two basic strategies to find out if something changed. You can poll, repeatedly check if anything is different. Or you can use an event, code that runs automagically when the change occurs. Events are of course much more effective, you don't waste any time and system resources to accomplishing little to nothing. You for example never poll a button to see if the user clicked it, you use its Click event instead.
Sometimes polling is inevitable, simply because an event is not available. But there certainly is one for a change to a file, the operating system has support for it. Exposed in .NET through the FileSystemWatcher class. Strongly recommended over a Timer or a worker thread, opening and reading every line of a file to discover a "I am done" string is very expensive.
Just be careful when you try to read the file. Also a problem when you use a Timer or worker thread, but more so because FileSystemWatcher works so much better. It is pretty likely that you can't open the file yet when the Change event fires because whatever process writes the file still has a lock on it. You may well still need a Timer to try to read the file later, after it is no longer locked.
You probably just want to use Timer. A sample code is something like this
var timer = new Timer(TimerTick, null, TimeSpan.Zero, new TimeSpan(0, 0, 0, 1));
int lastMinute = 1;
void TimerTick(object state)
{
var minute = DateTime.Now.Minutes;
if (minute != lastMinute && minute % 5 == 0)
{
lastMinute = minute;
//Check the .txt file
}
}
As Thorsten Dittmar pointed out, yes you probably want to use System.Timers.Timer than System.Threading.Timer. Timers.Timer is thread-safe too.
According to one of the answers from found here
The specific difference appears to be that System.Timers.Timer is geared towards multithreaded applications and is therefore thread-safe via its SynchronizationObject property, whereas System.Threading.Timer is ironically not thread-safe out-of-the-box.
I don't believe that there is a difference between the two as it pertains to how small your intervals can be.
There is also a link for a comprehensive explanation of timers.
There is already built in functionality to do this. Try using the FileWatcher class.
http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx
Related
Would anyone care to explain to me how the value of this.oBalance.QouteBalance is evaluated to be true for being less than zero when it clearly isn't? Please see image below.
Am I missing something fundamental when it comes to comparing doubles in C#??
public double QouteBalance { get; set; }
UpdateBalance_PositionOpenned() is not being called in a loop, but is being called as part of a more complex event driven procedure that runs on the ticks of a timer (order of milliseconds)
EDIT: Pardon the code if it's messy but I couldn't edit it as this was a run-time error after quite a long run-time so was afraid wouldn't be able to recreate it. The Exception message is not correct and just a reminder for myself. The code after the exception is code I forgot to comment out before starting this particular run.
EDIT 2: I am building and running in Release Mode.
EDIT 3: Pardon my ignorance, but it would seem that I am in fact running in a multi-threaded environment since this code is being called as part of a more complex object method that gets executed on the ticks (Events) of a timer. Would it possible to ask the timer to wait until all code inside its event handler has finished before it can tick again?
EDIT 4: Since this has been established to be a multi-threading issue; I will try to give wider context to arrive at an optimized solution.
I have a Timer object, which executes the following on every tick:
Run a background worker to read data from file
When background worker finishes reading data from file, raise an
Event
In the event handler, run object code that calls the method below
(in the image) and other multiple routines, including GUI updates.
I suppose this problem can be avoided by using the timer Tick events to read the from file but changing this will break other parts of my code.
You're accessing shared variables from multiple threads. It's probably a race condition where one thread has thrown the error but by the time the debugger has caught and attached, the variable's value has changed.
You would need to look at implementing synchronizing logic like locking around the shared variables, etc.
Edit: To answer your edit:
You can't really tell the timer to not tick (well you can, but then you're starting and stopping and even after calling Stop you might still receive a few more events depending on how fast they are being dispatched). That said, you could look at Interlocked namespace and use it to set and clear and IsBusy flag. If your tick method fires and sees you're already working, it just sits out that round and waits for a future tick to handle work. I wouldn't say it's a great paradigm but it's an option.
The reason I specify using the Interlocked class versus just using a shared variable against comes down to the fact you're access from multiple threads at once. If you're not using Interlocked, you could get two ticks both checking the value and getting an answer they can proceed before they've flipped the flag to keep others out. You'd hit the same problem.
The more traditional way of synchronizing access to shared data member is with locking but you'll quickly run into problems with the tick events firing too quickly and they'll start to back up on you.
Edit 2: To answer your question about an approach to synchronizing the data with shared variables on multiple threads, it really depends on what you're doing specifically. We have a very small window into what your application is doing so I'm going to piece this together from all the comments and answers in hopes it will inform your design choice.
What follows is pseudo-code. This is based on a question you asked which suggests you don't need to do work on every tick. The tick itself isn't important, it just needs to keep coming in. Based on that premise, we can use a flagging system to check if you're busy.
...
Timer.Start(Handle_Tick)
...
public void Handle_Tick(...)
{
//Check to see if we're already busy. We don't need to "pump" the work if
//we're already processing.
if (IsBusy)
return;
try
{
IsBusy = true;
//Perform your work
}
finally
{
IsBusy = false;
}
}
In this case, IsBusy could be a volatile bool, it could be accessed with Interlocked namespace methods, it could be a locking, etc. What you choose is up to you.
If this premise is incorrect and you do in fact have to do work with every tick of the timer, this won't work for you. You're throwing away ticks that come in when you're busy. You'd need to implement a synchronized queue if you wanted to keep hold of every tick that came in. If your frequency is high, you'll have to be careful as you'll eventually overflow.
This isn't really an answer but:
UpdateBalance_PositionOpenned() is not being called in a loop, but is
being called as part of a more complex event driven procedure that
runs on the ticks of a timer (order of milliseconds)
see:
Multi-threading? – abatishchev 30 mins ago
Tight timer driven event-loop on the order of milliseconds probably has all the problems of threads, and will be almost entirely impossible to trouble-shoot with a step-through debugger. Stuff is happening way faster than you can hit 'F10'. Not to mention, you're accessing a variable from a different thread each event cycle, but there's no synchronization in sight.
Not really a full answer but too much for a comment
This is how I could code defensively
Local scope leads to less unexpected stuff
And it make code easier to debug and test
public void updateBalance(double amount, double fee, out double balance)
{
try
{
balance = amount * (1.0 + fee);
if (balance < 0.0) balance = 0.0;
}
catch (Exception Ex)
{
System.Diagnostics.Debug.WriteLine(Ex.Message);
throw Ex;
}
}
Value type is copied so even if then input variable for amount changed while the method was executing the value for amount in the method would not.
Now the out balance without locks is a different story.
I need to create a method for listening to events and waiting for a certain amount of silence before calling another function.
Specifically, I am listening to a directory for file updates. When a file change occurs, my "directoryUpdate" function is called. From there I add the file to a list and create a thread called "timerThread" which sleeps for 2 seconds. When that thread is done sleeping, it calls a "gatherFinished" function.
But since directoryUpdate gets called 10 times all at once if 10 files change, it would launch 10 threads which seems like a bad way of doing this.
In the end I want a list of the file changes that occurred within 2 seconds of each other. I figure if there is a way to reset the sleep time to 2 seconds every time a change occurs and wait for the 2 seconds to finish, then I will have what I need. But there is no way to reset the timer as far as I know.
What is the best way of doing this?
UPDATE
Thanks for all your great answers. I am sorry for putting emphasis on getting the list of files. The event (file change) should not matter. I meant to focus on making sure the call to "gatherFinished" happens once at the right time - 2 seconds after all events in question have stopped firing. My question is on the nature of waiting, not on the nature of files or collections.
You could just use an AutoResetEvent and wait 2 seconds on it. If the event is triggered then you loop and wait another 2 seconds.
AutoResetEvent resetTimer = new AutoResetEvent(false);
...
private void TimerJob()
{
...
// The thread will sleep and loop until
// 2 seconds elapse without directory changes
while (resetTimer.WaitOne(2000)) {}
...
}
private void ResetTimer()
{
resetTimer.Set();
}
NOTE: I didn't put any code to specify you how to synchronize the thread that will receive the directory changes and the timer thread. You will have to do that youself.
One way of doing this would be to add each updated file to a list along with a timestamp of when they were added. Then, when your 2-second Timer fires, you can check for any items in the list that have a timestamp older than the last time it fired.
Hey Jono,
This is actually a really fun problem.
If I understand correctly you're using the FileSystemWatcher or some other similar object to monitor a folder.
Each time a file is added or changes, you receive an event.
Now the problem is that this event can be raised at relatively random times, and if you're trying to record all files which have been modified within 2 seconds of eachother, you're going to have many collections of objects.
What I would do is to create a List<List<MyFileChangeClass>> where MyFileChangeClass is whatever construct you use to track the information that changed.
When you handle the event for a file modification, create your new MyFileChangeClass with the necessary details and iterate the outer list. For each list, check to see if the first MyFileChangeClass has a time stamp of less than 2 seconds before the current file modification, if so, add your file modification to the inner list.
Once you're done walking the entire list, add a new List<MyFileChangeClass> to the outer list, which is populated with only the current MyFileChangeClass. This will ensure that future modifications can be associated with the latest one and that you have all groupings of modifications which occurred within 2 seconds of eachother.
Around the entire thing, I'd include a lock - probably a ReaderWriterLockSlim using TryEnterWriteLock().
I hope this helps - if you need more details, please let me know, but obviously you know a bit about what you're doing and probably just needed a bit of logic help because it's a strange problem.
Good luck!
Adam
I am going to assume that you are using the FileSystemWatcher class to monitor for file system changes. Your problem is well suited for the producer-consumer pattern. In your case the producer is the FileSystemWatcher which will add changed files to a queue. The consumer will then dequeue the file names from the queue once they appear. The nice thing about this pattern is that there is only one worker thread involved and all file changes will be processed in the order they are received.
Here is some code to get you started.
public class Example
{
private BlockingCollection<string> m_Queue = new BlockingCollection<string>();
public Example()
{
var thread = new Thread(Consumer);
thread.IsBackground = true;
thread.Start();
}
public void QueueChangedFile(string filePath)
{
m_Queue.Add(filePath);
}
private void Consumer()
{
while (true)
{
// The Take method blocks until an item appears in the queue.
string filePath = m_Queue.Take();
// Do whatever you need to do with the file here.
}
}
}
From the FileSystemWatcher event handlers you would call the QueueChangedFile. Add whatever code you think is necessary to process the file changes in the Consume method after the call to Take. You can make the logic as sophisticated as necessary. If you need to keep track of the time the changes occurred (so that you can later figure out which files were changed within 2 seconds of each other) then instead of having the queue hold a string you could create a simple class that stores both the file path and the change time and have the queue store that wrapper class instead.
I am developing an application in C# 4.0. I need to call a method depending on the current system time. Can I do it using Timer control? It would be great if someone could tell me how to do this.
Thanks,
Rakesh.
You may (and without knowing more about your app I cant say for sure) want to look at it a bit differently. You can easily write an app that sits around, doing nothing except polling what time it is, and then running whatever it is you need to do, but that will leave your application hanging around and doing nothing but taking up resources most of the time.
Instead, maybe you could consider creating a scheduled task, which will let you run your app at any given time. The Task Scheduler is documented at http://msdn.microsoft.com/en-us/library/aa383614(VS.85).aspx, and there is a managed wrapper for it at http://taskscheduler.codeplex.com/. (it says it works on XP or better, so hopefully it will cover your needs).
Good luck,
You can use the below code
System.Timers.Timer _timer1 = new System.Timers.Timer();
_timer1.Elapsed += new ElapsedEventHandler(_timer1_Elapsed);
//1 second
_timer1.Interval = 1000;
_timer1.Start();
//this event will be fired each 1 second
private void _timer1_Elapsed(object sender, ElapsedEventArgs e)
{
}
You should be able to, yes. Ghyath Serhal has told you how to use the timer class in general. The only bit missing is how to do it at a specific time. This should be pretty easy - when you set up the timer just take the time you want the action to happen and the current time, find the difference in seconds and use this to populare the interval. You'll also want to set the AutoReset property to false so that it doesn't start counting down immediately again.
If you ever change the time that the events happen you just need to hook into this with a trigger and update the timer to the new time.
Edit to add: If somebody were to change the system time that may cause problems with this plan. I'm not sure if you can easily tap into that to reset your timers. I'm guessing probably not relevant though. :)
The problem with timer is that it does not guarantee that the elapsed event would be called exactly at the right moment - all you know is that it would be called after time that is bigger than the Interval.
The solution is dependant on the resolution of the time you're interested in - for example if you need to check each minuet if a specific event occurs you can set a timer to raise the event every minuet and then use DateTime.Now to check if the system time is the time the event should occur.
A good policy is to always expect the timer elapsed event to happen several seconds after the Interval set depending on how busy the system is.
Alright...I've given the site a fair search and have read over many posts about this topic. I found this question: Code for a simple thread pool in C# especially helpful.
However, as it always seems, what I need varies slightly.
I have looked over the MSDN example and adapted it to my needs somewhat. The example I refer to is here: http://msdn.microsoft.com/en-us/library/3dasc8as(VS.80,printer).aspx
My issue is this. I have a fairly simple set of code that loads a web page via the HttpWebRequest and WebResponse classes and reads the results via a Stream. I fire off this method in a thread as it will need to executed many times. The method itself is pretty short, but the number of times it needs to be fired (with varied data for each time) varies. It can be anywhere from 1 to 200.
Everything I've read seems to indicate the ThreadPool class being the prime candidate. Here is what things get tricky. I might need to fire off this thing say 100 times, but I can only have 3 threads at most running (for this particular task).
I've tried setting the MaxThreads on the ThreadPool via:
ThreadPool.SetMaxThreads(3, 3);
I'm not entirely convinced this approach is working. Furthermore, I don't want to clobber other web sites or programs running on the system this will be running on. So, by limiting the # of threads on the ThreadPool, can I be certain that this pertains to my code and my threads only?
The MSDN example uses the event drive approach and calls WaitHandle.WaitAll(doneEvents); which is how I'm doing this.
So the heart of my question is, how does one ensure or specify a maximum number of threads that can be run for their code, but have the code keep running more threads as the previous ones finish up until some arbitrary point? Am I tackling this the right way?
Sincerely,
Jason
Okay, I've added a semaphore approach and completely removed the ThreadPool code. It seems simple enough. I got my info from: http://www.albahari.com/threading/part2.aspx
It's this example that showed me how:
[text below here is a copy/paste from the site]
A Semaphore with a capacity of one is similar to a Mutex or lock, except that the Semaphore has no "owner" – it's thread-agnostic. Any thread can call Release on a Semaphore, while with Mutex and lock, only the thread that obtained the resource can release it.
In this following example, ten threads execute a loop with a Sleep statement in the middle. A Semaphore ensures that not more than three threads can execute that Sleep statement at once:
class SemaphoreTest
{
static Semaphore s = new Semaphore(3, 3); // Available=3; Capacity=3
static void Main()
{
for (int i = 0; i < 10; i++)
new Thread(Go).Start();
}
static void Go()
{
while (true)
{
s.WaitOne();
Thread.Sleep(100); // Only 3 threads can get here at once
s.Release();
}
}
}
Note: if you are limiting this to "3" just so you don't overwhelm the machine running your app, I'd make sure this is a problem first. The threadpool is supposed to manage this for you. On the other hand, if you don't want to overwhelm some other resource, then read on!
You can't manage the size of the threadpool (or really much of anything about it).
In this case, I'd use a semaphore to manage access to your resource. In your case, your resource is running the web scrape, or calculating some report, etc.
To do this, in your static class, create a semaphore object:
System.Threading.Semaphore S = new System.Threading.Semaphore(3, 3);
Then, in each thread, you do this:
System.Threading.Semaphore S = new System.Threading.Semaphore(3, 3);
try
{
// wait your turn (decrement)
S.WaitOne();
// do your thing
}
finally {
// release so others can go (increment)
S.Release();
}
Each thread will block on the S.WaitOne() until it is given the signal to proceed. Once S has been decremented 3 times, all threads will block until one of them increments the counter.
This solution isn't perfect.
If you want something a little cleaner, and more efficient, I'd recommend going with a BlockingQueue approach wherein you enqueue the work you want performed into a global Blocking Queue object.
Meanwhile, you have three threads (which you created--not in the threadpool), popping work out of the queue to perform. This isn't that tricky to setup and is very fast and simple.
Examples:
Best threading queue example / best practice
Best method to get objects from a BlockingQueue in a concurrent program?
It's a static class like any other, which means that anything you do with it affects every other thread in the current process. It doesn't affect other processes.
I consider this one of the larger design flaws in .NET, however. Who came up with the brilliant idea of making the thread pool static? As your example shows, we often want a thread pool dedicated to our task, without having it interfere with unrelated tasks elsewhere in the system.
How can I have a WinForms program do some specific thing whenever a certain time-based condition is met?
I was thinking I could do something with two threads, where one thread runs the normal program, and the other thread merely loops through checking if the time-based condition is true yet or not, and when the condition is true it signals an event.
However I am unsure of the best way to do it. Where in the program would I call the two threads? Maybe I am thinking about it all wrong?
How would you do this?
MORE INFO:
What it has to do is check the data.dat file and see when the last time it was updated was. If it was a month or more then do the specific thing. Could this still be done with a Timer?
NOTE:
I think it might be useful to note the difference between the System.Timers and the System.Windows.Forms.Timer...
I think you should use a Timer set to an inteligent interval to check if your time-based condition is met.
It depends what your time-based condition is. Is it a special time or an interval after which you want to do something special? If it's the second, you can just use the Timer and do what you have to do when the Timer.Elapsed event is fired.
Edit after your edit:
If you want an event to be fired every time the file changes, use a FileSystemWatcher
Edit2:
Here's the difference between System.Windows.Forms.Timer and System.Timers:
The Windows Forms Timer component is
single-threaded, and is limited to an
accuracy of 55 milliseconds. If you
require a multithreaded timer with
greater accuracy, use the Timer class
in the System.Timers namespace.
You could add a System.Windows.Forms.Timer control to your Form (see the Components category in the toolbox).
Then set the timer's interval to some value (e.g. 1000) and add a handler for its Tick event. This handler will then be called once every 1000 milliseconds.
In the handler you can then check if the conditions are met and if yes, start your specific operation.
Update (after you updated the question):
To check if the last modification of a file was more than one month ago, you can use this code:
if (File.GetLastWriteTime("data.dat").AddMonths(1) < DateTime.Now)
{
// do whatever has to be done
// if it is a time-consuming task, start a new thread!
}
You can still put this into the Tick event handler of the timer component. But in that case it does probably not make sense to fire the timer every second.
Depending on your application (e.g. if it will be started quite often), another possibility would be to execute the above check during the startup of your application.
Regarding your 'more info':
How many times must it check the modification-date of that specific file ?
Only once (during startup for instance), or should it check the modification-date of that file multiple times during application execution ?
If it has to be done only once, then it is useless to use a timer.
If it has to be done multiple times, then yes, you could use a timer.
The eventhandler of the Elapsed event could then check the ModificationDate of the file, and see if action needs to be taken.
Another solution, which is probably more elegant, is using a FileSystemWatcher.
This FileSystemWatcher could 'watch' that particalur file.
Specify a Filter on the FileSystemWatcher so that, every time the particular File is changed, an event is raised.
In the eventhandler of the FileSystemWatcher, you can then take the necessary action:
FileSystemWatcher dataFileWatcher = new FileSystemWatcher();
dataFileWatcher.Path = "path to your file";
dataFileWatcher.Filter = "yourfilename";
dataFileWatcher.Changed += new FileSystemEventHandler(OnFileChanged);
dataFileWatcher.NotifyFilter = NotifyFilters.LastWrite;
dataFileWatcher.EnableRaisingEvents = true;
private void OnFileChanged( object sender, FileSystemEventArgs e )
{
// take action.
}
Note however, that there's a sublte bug / feature in the FileSystemWatcher which causes that the Changed event gets raised multiple times for one change to the File you're watching.
You can resolve this like this
Another alternative, if you know the time between file updates (a month) is to check once at startup time. If the file is out of date you can process it immediately. If not, you can then work out how long you need to wait before checking it again. You can then schedule a task using a wait timer or other methods as described in the answers.
Basically, at startup time you can find out the limit/worst case on how long you have to wait and then you don't need to do any additional checks in the meantime. This assumes of course that the file can't be changed to an OLDER version during the running of the program which seems unlikely, but not impossible!