当另一个带有try-catch的线程仍处于活动状态时,主线程无法捕获异常(该异常已在主线程中引发)。怎么解决呢? 例如:
private void SetText(IWebElement element, string text, bool clearOldText)
{
// Clear old text if needed
if (clearOldText)
{
LogInfo("Clearing " + element.ToString() + @" from any text.");
SetElementValue(element, "");
}
element.Click();
SetElementValue(element, text);
}
public string SetElementValue(IWebElement element, string value)
{
ScrollToElement(element);
PaintElement(element, "yellow");
var exec = (IJavaScriptExecutor)this;
var script = @"
var el = arguments[0];
el.value = '" + value + @"';
try
{
if (""createEvent"" in document) {
var evt = document.createEvent(""HTMLEvents"");
evt.initEvent(""change"", false, true);
el.dispatchEvent(evt);
}
else
el.fireEvent(""onchange"");
}
catch(err){ return err; }
return ""Javascript executed."";
";
LogInfo("Setting value to '" + value + "' for " + element.ToString());
var result = exec.ExecuteScript(script, element);
Recorder?.AddScreenshot();
return result.ToString();
}
答案 0 :(得分:3)
不是因为捕获可连接线程会终止进程而捕获了异常,而是因为没有捕获到异常。 因此,您的程序将在执行异常处理程序之前终止。
如果在try-catch块之外声明线程,则将捕获异常。
请记住,如果引发了异常,则还需要加入线程。
答案 1 :(得分:2)
您出了点问题。我的意思是,您误解了一些东西。
这与尝试捕获无关。 “ throw”和“ try-catch”是线程内的东西,它们仅存在于当前线程上,无论在主线程或其他线程抛出时处于何种状态。
另一个线程无法捕获从当前线程引发的异常。异常不会跨越线程,除非您确实想要并实现它,例如,当前线程上的某些东西捕获了异常并将其传递给其他线程,然后在那里重新抛出/等这些异常。您没有任何此类的东西,所以不可能。
掷球后您有一个join()
通话,希望throw 1
会跳过。确实如此。但是,范围中还有std::thread cThread
变量。
由于该线程正在运行,并且由于尚未throw 1
对该线程进行join()处理,因此要查看的预期是程序终止 strong>(请参阅https://stackoverflow.com/a/13984169/717732),因为std :: thread的析构函数会检测到un-join()线程。这就是说,std::cout << "Catched exception " << e << " in main";
绝对不能被调用。即使线程以某种方式完成了,您的程序仍应终止,因为它不会改变未加入()的事实(请参见https://en.cppreference.com/w/cpp/thread/thread/joinable)
但是,根据库,编译器,调试器等的不同,您看到的效果可能有所不同。例如,如果在调试器中运行它,则它可能要等到所有线程完成后才能得到“等到内部线程完成”的效果。很难说。
如果您实际上看到"Catched exception " << e << "
行正在运行,那么您就遇到了真正的问题。您正在运行的不是当前代码,而是您的stdlib损坏了。例如,损坏的stdlib可能在std :: thread的析构函数中执行无提示join()而不是终止程序。谁知道。损坏的lib可以做很多事情。
答案 2 :(得分:0)
感谢molbdnilo和quetzalcoatl。 现在,我通过使用std :: async而不是std :: thread:
使代码工作首先,问题与线程中的try-catch无关。认为是我的错误。所以这是一个失败代码:
int main()
{
// try-catch of main thread
try
{
// run a thread
std::thread cThread([]()
{
});
// Any call to throw BEFORE thread join won't be catch.
// HOW TO SOLVE IT??
throw 1;
// wait thread finished
cThread.join();
// IF YOU PUT THE "throw 1" HERE (AFTER THREAD FINISHED), IT WILL BE
// CATCH.
}
catch (int e)
{
std::cout << "Catched exception " << e << " in main";
}
return 0;
}
和有效的代码:
int main()
{
std::future<void> cF;
// try-catch of main thread
try
{
// run a thread
cF = std::async(std::launch::async, []()
{
});
// You can call throw , it will be catch :)
throw 1;
// wait thread finished
if (cF.valid())
{
cF.get();
}
}
catch (int e)
{
std::cout << "Catched exception " << e << " in main";
}
return 0;
}