【问题标题】:Is there any way to see the full stack trace across multiple threads?有没有办法跨多个线程查看完整的堆栈跟踪?
【发布时间】:2017-06-13 23:57:12
【问题描述】:

在 C# 多线程编程中,当方法 A() 在新线程中调用方法 B() 时,例如通过使用这样的东西:

Task A()
{
    // ...

    // I want B to run in parallel, without A() waiting for it.
    Task.Factory.StartNew(B); 
}

void B()
{
     // I attach a debugger here to look at the Call Stack.
     // But that is empty and I can't see that A() actually called it (logically).

     // Also Environment.StackTrace is pretty much empty of that path.
}

换句话说,在方法 B() 内部,堆栈跟踪对方法 A() 的调用路径一无所知,这反过来又触发了方法 B() 的执行。

有没有办法查看完整的逻辑堆栈跟踪,例如在B() 出现异常的情况下,您可以查看完整故事以了解A() 实际上叫它吗?

【问题讨论】:

  • @SimonPrice,这就是调试多线程程序的一般方法。 OP 正在寻找一种方法来找出哪个线程(以及调用堆栈到该点)启动了另一个线程/计划了一个任务,如果该任务引发异常。有什么更具体的吗?
  • 我已经用更多细节更新了这个问题。您可以在 Visual Studio 中轻松创建此场景以亲自查看。
  • 如果有帮助,我正在 UWP 应用程序中对此进行测试。
  • 未捕获此信息。一个新的线程是一个新的起点。你能得到的最好的方法是给你的线程一个有用的名字。

标签: c# multithreading async-await task-parallel-library visual-studio-debugging


【解决方案1】:

通常答案是No,因为StackTrace 根据定义不能包含来自其他堆栈的信息。但是,如果您在 Visual Studio 中调试应用程序,它会为您完成一些工作(这是 C++,但所有语言都类似):

在这里,外部代码比您的要暗淡,您可以查看一些“父”线程信息。但是,通常这个屏幕并没有多大帮助。 Visual Studio 创建vshost.exe 文件以收集尽可能多的调试信息。

此外,如果您创建任务时将它们附加到父级,并且有一些异常,您将使用异常的 ToString 方法获得完整的堆栈跟踪,但这仍然不是您想要的。

【讨论】:

  • 我最终创建了自己的 SynchronizationContext 来跟踪嵌套线程调用。
  • @Paymon 你能更详细地解释一下你最终得到了什么吗?
  • 解释起来有点复杂。我几乎在我们的框架中围绕多线程设计了一个完整的 API 以使其工作。我怀疑你想去那里。
猜你喜欢
  • 2015-10-03
  • 2013-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-22
  • 2012-07-07
  • 1970-01-01
  • 2011-11-11
相关资源
最近更新 更多