背景。 我的腳本在遞歸搜索大字符串中的特定文本時遇到StackOverflowException。循環不是無限的;在9,000-10,000個合法搜索之間出現問題(對於特定搜索) - 我需要繼續。我使用尾遞歸(我認爲),這可能是我的問題的一部分,因爲我收集C#不這樣做。但是,我不確定如何避免在我的情況下使用尾遞歸。StackOverflowException在非無限遞歸字符串搜索中
Question(s)。爲什麼會發生StackOverflowException?我的整體方法是否有意義?如果設計很糟糕,我寧願從那裏開始,而不僅僅是避免一個例外。但是,如果設計是可以接受的,我可以做些什麼關於StackOverflowException?
代碼。 我寫的這個類在大量文本(大約6MB)中搜索聯繫人(大約來自指定列表的500+)。我正在使用的策略是搜索姓氏,然後在姓氏前後的某處查找姓氏。我需要找到給定文本中每個聯繫人的每個實例。 StringSearcher類有一個遞歸方法,它繼續搜索聯繫人,每當找到一個結果時都會返回結果,但會跟蹤搜索結束後的位置。
我使用這個類以下列方式:
StringSearcher searcher = new StringSearcher(
File.ReadAllText(FilePath),
"lastname",
"firstname",
30
);
string searchResult = null;
while ((searchResult = searcher.NextInstance()) != null)
{
// do something with each searchResult
}
就整體而言,劇本似乎工作。大多數聯繫人返回我期望的結果。但是,當主搜索字符串非常常見(成千上萬次點擊)並且次搜索字符串從不或很少發生時,問題似乎就會發生。我知道它沒有被卡住,因爲CurrentIndex正常前進。
這是我正在談論的遞歸方法。
public string NextInstance()
{
// Advance this.CurrentIndex to the next location of the primary search string
this.SearchForNext();
// Look a little before and after the primary search string
this.CurrentContext = this.GetContextAtCurrentIndex();
// Primary search string found?
if (this.AnotherInstanceFound)
{
// If there is a valid secondary search string, is that found near the
// primary search string? If not, look for the next instance of the primary
// search string
if (!string.IsNullOrEmpty(this.SecondarySearchString) &&
!this.IsSecondaryFoundInContext())
{
return this.NextInstance();
}
//
else
{
return this.CurrentContext;
}
}
// No more instances of the primary search string
else
{
return null;
}
}
的StackOverflowException在下面的方法上this.CurrentIndex = ...
發生:
private void SearchForNext()
{
// If we've already searched once,
// increment the current index before searching further.
if (0 != this.CurrentIndex)
{
this.CurrentIndex++;
this.NumberOfSearches++;
}
this.CurrentIndex = this.Source.IndexOf(
this.PrimarySearchString,
ValidIndex(this.CurrentIndex),
StringComparison.OrdinalIgnoreCase
);
this.AnotherInstanceFound = !(this.CurrentIndex >= 0) ? false : true;
}
如果需要的話,我可以包括更多的代碼。讓我知道這些方法或變量之一是否有問題。
*表現不是真正的問題,因爲這可能會在晚上作爲計劃任務運行。
+1感謝您解釋發生異常的原因。我認爲按照您的建議使用迭代器是最好的設計方法。 –