2015-01-07 5 views
0

특정 웹 페이지에서 콘텐츠를 다운로드하고 content이라는 문자열 변수에 넣는 C# winforms 응용 프로그램이 있습니다. 그런 다음 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); 
    } 
} 

감사합니다.

답변

1

아마도 더 잘 작동하는 것은 발견 된 키워드와 발견 된 시간을 추가하는 Dictionary<string, DateTime>을 만드는 것입니다. 그런 다음 몸 타이머를 통해 호출되는 방법을 만들 :

foundKeywordsDict = foundKeywordsDict.Where(kvp => kvp.Value > DateTime.Now.AddMinutes(-5)) 
        .ToDictionary(kvp => kvp.Key, kvp = > kvp.Value) 

이것이 모든 키워드가 마지막 5 분 이내에 추가 된 기존에서 새 사전을 만들 수있다 할 것입니다.

EDIT : C#에는 System.Timers.TimerSystem.Threading.Timer의 두 가지 유형의 타이머가 있습니다. 다음은 나중에 사용합니다. System.Threading.Timer을 사용하면 Timer은 타이머가 작동 할 때 새 스레드를 만들고 생성자에서 전달한 TimerCallback 대리자를 호출 한 다음 타이머를 다시 시작합니다. TimerCallback은 서명이 void MethodName(object state) 인 메소드 만 허용합니다 (정적 일 수 있음). 온

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 

추가 정보 :이 비슷한을 원하는 것이

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) 
} 

타이머를 만들려면 : 귀하의 경우를 들어

, 당신은 당신의 코드는 다음에 유사 할 것 System.Threading.Timer 클래스는 here이고 System.Timers.Timer 클래스의 정보는 here이고 lock 키워드에 대한 정보는 here입니다. 당신이 정기적으로 foundKeywordsList을 삭제하려면

+0

타이머를 구현하는 방법에 대한 예제를 제공해 주시겠습니까? –

+0

감사합니다. Btw, RemoveOldFoundKeywords를 매우 간결하고 명확한 방법으로 디버깅하려고 시도했지만, 오로지 (분명히 debbuging 할 때만) 작동합니다. 그 이상한 행동에 대한 이유가 있습니까? –

+0

일관되게 작동해야합니다. 메서드는 5 분 이상 오래된 항목 만 제거하는 동안 타이머가 매분마다 실행됩니다.메서드가 호출 될 때 예외가 발생합니까? 아니면 아무 일도 일어나지 않았습니까? – JRLambert

0

, 당신이 시도 할 수 :

// 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에 액세스 할 때 잠금 블록을 추가해야하고 명확 동시에 발생하지 않습니다.

+0

사실 저는 전체 목록을 지우고 싶지 않고 첫 번째 요소 만 제거합니다. –