gpt4 book ai didi

c# - 在 C# - C++/CLI - C++ Windows 窗体应用程序退出之前跟踪 - 并正确结束 - native 和托管线程

转载 作者:行者123 更新时间:2023-11-28 08:27:54 26 4
gpt4 key购买 nike

这是后续的:

Debugging a Multithreaded C# - C++/CLI - C++ Solution in Visual Studio 2008: What are these threads?

请原谅格式,我只是在这里重复了一些应用程序的描述:

我继承了一个由三层代码组成的项目。最低层是与硬件交互的 native C++。这是成熟、稳定和经过充分测试的。中间层代码是 C++/CLI,它与包含 UI 元素和一些附加功能的顶层 C# 代码交互。此 C# 代码不完整且开发仓促:它经常崩溃且不符合用途。我的任务是调试并完成它。

我从上一个问题中收到了一些非常有用的信息 - 但现在有更多问题!我现在的问题是,当我调用 Application.Exit() 来关闭 UI 并退出应用程序时,会抛出一个异常:

System.InvalidOperationException: Collection was modified; enumeration operation may not execute

我知道这是因为我需要确保在调用 Application.Exit()(或 Application.ExitThread())之前我的所有线程都已结束。我在进一步调查时尝试使用 MainForm.Close() 作为快速修复,但它并没有缓解问题。

我不想只调用 Thread.CurrentThread.Abort(),主要是因为一些线程源自代码的 C++ 部分,通过 Boost::Thread,我不确定我可以使用哪些资源处于不希望的状态(很多代码由与硬件交互的对象组成,例如串行端口——它不是通过 RAII 实现的,所以我对暴力强制操作相当谨慎)。

我想做的是识别哪些线程正在做什么,并在退出应用程序之前优雅地结束它们。然而,在 VS 2008 中,堆栈跟踪 - 激活“显示外部代码” - 仅显示

[Native to managed transition]
[Managed to native transition]

所以我仍然难以跟踪各个 native 线程,因此无法找到结束它们的最佳方法。

我尝试使用 Allinea DDTLite,它看起来很棒 - 但我在安装 VS 时遇到了一些问题,我不得不禁用插件,所以这不是解决方案。

总结一下:确保所有线程(包括托管线程和 native 线程)正确完成的最有效方法是什么,以便 UI,然后是整个应用程序可以干净地退出吗?

最佳答案

What I'd like to be able to do is identify what threads are doing what

你无法完成这项工作。有一些方法可以枚举进程中的线程,例如托管 Process.Threads 属性或 native Thread32First/Next,但您几乎没有获得足够的关于线程的信息来了解它们的作用。而且肯定不会彻底关闭它们。 .NET 框架为了自己的目的使用线程,如调试器线程和终结器线程以及少量线程池线程,这进一步复杂化了。

您可以使用 TerminateThread 粗暴地杀死这些线程,尽管杀死终结器线程会立即使程序崩溃,但这与使用 Environment.Exit() 粗暴地终止进程没有什么不同。需要注意的是,没有任何东西可以很好地清理干净。不过,Windows 会清除大部分弹片。

这通常不是问题。你知道你启动了哪些线程,还应该有一种机制来要求它们关闭。这通常是通过发出事件信号来完成的,这在线程的主循环中进行了测试。等待线程句柄确认线程确实退出。之后您可以关闭窗口。

但这可能是缺少管道,您必须添加它。如果当前的 native C++ 代码没有处理线程关闭的机制,那么你就会遇到一个相当大的问题。我猜维护这个本地 C++ 代码才是真正的问题。您可能需要雇用一把枪才能完成这项工作。

关于c# - 在 C# - C++/CLI - C++ Windows 窗体应用程序退出之前跟踪 - 并正确结束 - native 和托管线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3289149/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com