我有一个主线程充当作业调度程序。它从数据库查询术语并将这些术语分派(dispatch)给异步 Web I/O。当Web响应到达时,ThreadPool将调度一个线程来处理该响应并保存到DB。
StackOverflowException 发生在主线程中。它使用 Entity Framework 从数据库中获取一堆术语。代码如下。
目前,我想知道:当我使用BeginGetResponse()方法为线程池生成工作项时,工作项放置在哪里?在主线程的堆栈中?这可能是 StackOverflow 的原因吗?如果是这样,我应该放慢工作项的生成速度吗?
有没有办法:
- 确定哪个线程的堆栈溢出?
溢出堆栈的内容是什么?
while(!jobDone) { while(availableBatchQuota<=0) { polling = true; Thread.Sleep(pollingInterval); Console.Write("\rPolling..."); } if (polling) { Console.WriteLine(); polling = false; } //At least 1 quota is available if (terms.Any()) <=========StackOverflow exception here! { Interlocked.Decrement(ref availableBatchQuota); SearchTermsDistinct term = terms.Take(1).ToList()[0]; ContextlessTerm term2 = new ContextlessTerm(); term2.Term = term.Term; term2.TermId = term.Term_ID; SearchAsync(term2, 1); terms = terms.Skip(1); } else jobDone = true; }
--
public static void SearchAsync(ContextlessTerm term, Int32 pageIndex)
{
String processedTerm = TermPreProcess.Process(term.Term);
if (processedTerm.Length == 0) return; // if the term is empty, we shouldn't search it.
Console.WriteLine("Searching term: {0}", processedTerm);
String query = String.Format(queryString, processedTerm, (pageIndex - 1) * 10 + 1);
//Console.WriteLine(query);
WebRequest request = WebRequest.Create(query);
request.Proxy = null;
request.Method = "GET";
request.BeginGetResponse(ar =>
{
List<mySearchResultClass> resultsOnePage = null;
using (WebResponse response = request.EndGetResponse(ar))
{
resultsOnePage = GetResultURLsForOnePage(response.GetResponseStream());
Int32 rank = 1;
foreach (var result in resultsOnePage)
{
result.Rank = (pageIndex - 1) * 10 + rank;
rank++;
}
}
lock (dbSync)
{
SaveToDB(term, resultsOnePage);
}
if (pageIndex < maxSearchPages && resultsOnePage.Count() == 10) SearchAsync(term, pageIndex + 1);// relay race!
else
{
Interlocked.Increment(ref availableBatchQuota);
Interlocked.Increment(ref progress);
//Console.ForegroundColor = ConsoleColor.Cyan;
//Console.WriteLine("Done searching term: {0}", processedTerm);
Console.WriteLine("{0}: Available: {1}\tProgress:{2:f3}%", DateTime.Now.ToString(), availableBatchQuota, progress * 100.0 / totalTerms);
//Console.ResetColor();
}
}, null);
}
添加1
下面是我在“DEBUG”->“Threads”窗口中看到的内容。看来是主线程出了问题。
添加2
堆栈跟踪。
添加3
我刚刚重新运行我的应用程序,这次异常发生在同一个地方,但是有问题的 DLL 更改为 EntityFramework.dll。太奇怪了...
An unhandled exception of type 'System.StackOverflowException' occurred in EntityFramework.dll
最佳答案
如果没有看到你的堆栈跟踪,提供明确的答案有点困难,但我认为坚持基础知识会让我相信你的 StackOverflow 的来源是
SearchAsync(ContextlessTerm term, Int32 pageIndex)
它调用自己:
if (pageIndex < maxSearchPages && resultsOnePage.Count() == 10) SearchAsync(term, pageIndex + 1);// relay race!
您是否分析过您的代码以了解您的递归平均深度有多深?它总是会出现 StackOverflow,还是仅在某些情况下出现?
关于c# - mscorlib.dll 中发生“System.StackOverflowException”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24298364/