线程无一例外地被杀死

Posted

技术标签:

【中文标题】线程无一例外地被杀死【英文标题】:Thread get killed without exception 【发布时间】:2021-05-21 16:18:24 【问题描述】:

我得到 cItems,这是 Selenium 提供的 IReadOnlyCollection<IWebElement>。 然而。我制作了基于单线程的功能,它工作得很好。但现在我想提高性能,所以我选择了 .Net ThreadPool

ThreadPool.SetMaxThreads(16, 16);

IEnumerator<IWebElement> iter = cItems.GetEnumerator();
while(iter.MoveNext()) 
  cThreadJobObj.Item = iter.Current;
  ThreadPool.QueueUserWorkItem(new WaitCallback(GetThreadJob), cThreadJobObj.Clone()); // .Clone() is a deep clone


现在的问题是,线程在第 5 行消失了。我认为没有抛出任何异常,我认为是因为没有调用 catch (Exception Ex) 块。

public static void GetThreadJob(object ThreadJob) 
  try 
    var cThreadJob = ThreadJob as ThreadJobObj;
    var IWebElement = cThreadJob.Item;
    var cElem = cItem.FindElement(By.CssSelector("span.im_message_date_text"));
   catch (Exception Ex) 
    Rupert.Logger.E("Thread.GetCurrentProcessorId() on Obj cThreadJob.iCount", Ex, false);
  

GetThreadJob 被所有 16 个线程调用,并且全部消失在同一行。

更新

我在这个方法ISearchContext.FindElement Method中分离了行,线程消失了。

IWebElement.FindElement(By)

如果我在这条线上做一个快速观察,这就是价值:

cItem.FindElement(cSel) Function evaluation disabled because a previous function evaluation timed out. You must continue execution to reenable function evaluation. OpenQA.Selenium.IWebElement

【问题讨论】:

如果你在调试器中运行它并设置了“Break on throw”(调试菜单..异常.. CLR旁边的勾号),它会中断吗? @CaiusJard 现在,我勾选了每一个。它们都消失在同一条线上。 但是线是什么?是否有任何异常被抛出? @CaiusJard 没有抛出任何东西。 var cElem = cItem.FindElement(By.CssSelector("span.im_message_date_text")); 在这里线程消失了。我可以看到,因为我在前后都做了一个Console.WriteLine。此外,在调试期间,进程切换到下一个等待线程。如果都通过了这一行,则程序正在等待 I/O,因为到达底部的回调。 【参考方案1】:

好的,经过漫长的一夜之后,我发现 .Net 限制了在 Selenium 进程期间可以打开的套接字。

ServicePointManager.DefaultConnectionLimit 的默认值为 2,Asp.net 的默认值为 10。 More Info

这可以通过在脚本的初始化中避免:

         ThreadPool.SetMinThreads(Environment.ProcessorCount / 2, 25);
         ThreadPool.SetMaxThreads(Environment.ProcessorCount * 4, 100);

         ServicePointManager.UseNagleAlgorithm = true;
         ServicePointManager.Expect100Continue = true;
         ServicePointManager.DefaultConnectionLimit = 65000;
         ServicePointManager.MaxServicePointIdleTime = 500;

【讨论】:

以上是关于线程无一例外地被杀死的主要内容,如果未能解决你的问题,请参考以下文章

致命例外:JavaBridge - 只有创建视图层次结构的原始线程才能接触其视图

例外:使用 Spring Client 对 Spring 中的 http-epoll-1 线程进行泄漏检测

oracle 例外

Oracle_PL/SQL 例外处理

Oracle PL/SQL学习之基础篇--例外

PLSQL例外处理