I have a c# winforms application which downloads content from certain webpages and puts it in a string variable called content
. It then searches for specific keywords (contained in a string, and separated by comma) within content
, and sounds an alarm if there's a match; otherwise, makes another webrequest and run the search again.
My client asked for something different: He wants the program to keep running after it finds a keyword and triggers the alarm, but this time it should only look for the remaining keywords that were not found in the last 5 minutes.
I thought about adding found keywords to a dynamic array, called foundKeywordsList
, and starting a stopwatch or some kind of timer to remove them from the array after 5 minutes' passed, but I don't know how to do just that, so that's my question. So far this is the relevant code (it runs inside a loop):
List<string> foundKeywordsList = new List<string>();
string keywords = "scott,mark,tom,bob,sam";
string[] keywordArray = keywords.Split(',');
foreach (string kw in keywordArray)
{
// Performs search only if the keyword wasn't found in the last 5 minutes
if (!foundKeywordsList.Contains(kw) && content.IndexOf(kw) != -1)
{
//
// code for triggering the alarm
//
foundKeywordsList.Add(kw);
}
}
Thanks everyone.
What would probably work better is to create a Dictionary<string, DateTime>
where you add the found key word and the time that it was found. Then create a method that is called via a timer with the body:
foundKeywordsDict = foundKeywordsDict.Where(kvp => kvp.Value > DateTime.Now.AddMinutes(-5))
.ToDictionary(kvp => kvp.Key, kvp = > kvp.Value)
What this will do is create a new dictionary from the existing one where all the keywords have been added within the last 5 min.
EDIT:
There are two types of timers in c#, the System.Timers.Timer
and the System.Threading.Timer
. The following is using the later. Using the System.Threading.Timer
, the Timer
will create a new thread when the timer hits, calling the TimerCallback
delegate that you pass in the constructor, and restart the timer. The TimerCallback
only accepts methods with the signature of void MethodName(object state)
(it can be static).
For your case, you would want your code to look similar to this:
public void RemoveOldFoundKeywords(object state)
{
lock(foundKeywordsDict) //since you are working with threads, you need to lock the resource
foundKeywordsDict = foundKeywordsDict.Where(kvp => kvp.Value > DateTime.Now.AddMinutes(-5))
.ToDictionary(kvp => kvp.Key, kvp = > kvp.Value)
}
To create the timer, you would want something similar to this:
Using System.Threading;
....
int timerInterval = 60*1000 //one minute in milliseconds
TimerCallback timerCB = new TimerCallback(RemoveOldFoundKeywords);
Timer t = new Timer(
timerCB, //the TimerCallback delegate
null, //any info to pass into the called method
0, //amount of time to wait before starting the timer after creation
timerInterval); //Interval between calls in milliseconds
Additional information on the System.Threading.Timer
class can be found here, info for the System.Timers.Timer
class can be found here and info for the lock
keyword can be found here.