如何在有限的时间内将变量保存在动态数组中
How to keep variables in dynamic array for a limited time
我有一个 c# winforms 应用程序,它从某些网页下载内容并将其放入一个名为 content
的字符串变量中。然后在content
中搜索特定的关键字(包含在一个字符串中,用逗号分隔),如果匹配则发出警报;否则,发出另一个网络请求并再次运行搜索。
我的客户提出了一些不同的要求:他希望程序在找到关键字并触发警报后继续运行,但这次它应该只查找最近 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>
,在其中添加找到的关键字和找到它的时间。然后创建一个通过计时器调用的方法,主体为:
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
class 的更多信息,请参见 here, info for the System.Timers.Timer
class can be found here and info for the lock
keyword can be found here。
如果你想定期清除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 时添加锁块,以确保添加和清除不会同时发生。
我有一个 c# winforms 应用程序,它从某些网页下载内容并将其放入一个名为 content
的字符串变量中。然后在content
中搜索特定的关键字(包含在一个字符串中,用逗号分隔),如果匹配则发出警报;否则,发出另一个网络请求并再次运行搜索。
我的客户提出了一些不同的要求:他希望程序在找到关键字并触发警报后继续运行,但这次它应该只查找最近 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>
,在其中添加找到的关键字和找到它的时间。然后创建一个通过计时器调用的方法,主体为:
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
class 的更多信息,请参见 here, info for the System.Timers.Timer
class can be found here and info for the lock
keyword can be found here。
如果你想定期清除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 时添加锁块,以确保添加和清除不会同时发生。