如何在有限的时间内将变量保留在动态数组中

本文关键字:保留 变量 动态 数组 时间 | 更新日期: 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.TimerSystem.Threading.Timer 。以下是使用后面的。使用 System.Threading.TimerTimer将在计时器命中时创建一个新线程,调用您在构造函数中传递的 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 时,您需要添加锁定块,以确保添加和清除不会同时发生。