如何在有限的时间内将变量保留在动态数组中
本文关键字:保留 变量 动态 数组 时间 | 更新日期: 2023-09-27 18:36:27
我有一个 c# winforms 应用程序,它从某些网页下载内容并将其放入名为 content
的字符串变量中。然后,它会搜索content
内的特定关键字(包含在字符串中,并用逗号分隔),并在匹配时发出警报;否则,发出另一个 Web 请求并再次运行搜索。
我的客户要求一些不同的东西:他希望程序在找到关键字并触发警报后继续运行,但这次它应该只查找过去 5 分钟内未找到的剩余关键字。
我想过将找到的关键字添加到一个名为 foundKeywordsList
的动态数组中,并在 5 分钟后启动秒表或某种计时器将它们从数组中删除,但我不知道该怎么做,所以这是我的问题。到目前为止,这是相关的代码(它在循环中运行):
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);
}
}
谢谢大家。
可能更好的方法是创建一个Dictionary<string, DateTime>
,在其中添加找到的关键字和找到它的时间。然后创建一个通过带有 body 的计时器调用的方法:
foundKeywordsDict = foundKeywordsDict.Where(kvp => kvp.Value > DateTime.Now.AddMinutes(-5))
.ToDictionary(kvp => kvp.Key, kvp = > kvp.Value)
这将从现有字典创建一个新字典,其中所有关键字都已在过去 5 分钟内添加。
编辑:C# 中有两种类型的计时器,System.Timers.Timer
和 System.Threading.Timer
。以下是使用后面的。使用 System.Threading.Timer
,Timer
将在计时器命中时创建一个新线程,调用您在构造函数中传递的 TimerCallback
委托,并重新启动计时器。TimerCallback
仅接受具有 void MethodName(object state)
签名的方法(可以是静态的)。
对于您的情况,您可能希望您的代码类似于以下内容:
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)
}
要创建计时器,您需要类似以下内容:
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
有关System.Threading.Timer
类的其他信息可在此处找到,System.Timers.Timer
类的信息可在此处找到,lock
关键字的信息可在此处找到。
定期清除foundKeywordsList,你可以试试这个:
// Invoke the background monitor
int _5mins = 5 * 60 * 1000;
System.Threading.Tasks.Task.Factory.StartNew(() => PeriodicallyClearList(foundKeywordsList, _5mins));
// Method to clear the list
void PeriodicallyClearList(List<string> toClear, int timeoutInMilliseconds)
{
while (true)
{
System.Threading.Thread.Sleep(timeoutInMilliseconds);
toClear.Clear();
}
}
在访问 foundKeywordsList 时,您需要添加锁定块,以确保添加和清除不会同时发生。