c# – 在任务中抛出异常时处理泄漏
我试图理解应用程序中发生的一个非常奇怪的句柄泄漏.
我已设法在以下代码中隔离问题: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication2 { public class EventRaiser { public event EventHandler OnEvent; public void DoSomething() { Console.Write("."); try { throw new Exception("?"); } catch (Exception e) { } if (OnEvent != null) OnEvent(this,null); } } public class EventConsumer { private EventRaiser m_Event; public EventConsumer() { m_Event = new EventRaiser(); m_Event.OnEvent += m_Event_OnEvent; } public void Start() { m_Event.DoSomething(); } private void m_Event_OnEvent(object sender,EventArgs e) { Task.Run(() => m_Event.DoSomething() ); // 4.5 //Task.Factory.StartNew(() => m_Event.DoSomething()); // 4.0 } } class Program { private static EventConsumer x; static void Main(string[] args) { x = new EventConsumer(); x.Start(); Console.ReadLine(); } } } 这样,这个测试应用程序非常快速地提升到23721个句柄(5秒就足以达到这个值) 但是,删除“throw new Exception”行,应用程序在运行几分钟时保持稳定,大约有450个句柄. 知道这里有什么问题吗? 谢谢! 编辑#1 由于问题的警告不可重现,我注意到只有在Visual Studio内部以调试模式运行时才会发生这种情况(2013和2015 Professional中的结果相同). 编辑#2 今天,我使用完全相同版本的Visual Studio(2013 Pro 12.0.40629.00 Update5)在另一台计算机上测试了完全相同的项目,但是这一个在Windows 8.1中运行(我的计算机运行的是Windows 10),我是无法在这里重现问题. 编辑#3 我刚刚在运行Windows 10和Visual Studio 2015 Pro的另一台计算机上测试过,问题没有发生!现在我非常困惑,因为我在Visual Studio 2015 Pro中运行时在计算机中遇到同样的问题而且我没有安装特殊扩展.我想我会用周末来完全重新安装系统. 解决方法
这可能是因为.NET中的关键部分创建行为.如你所知,catch块几乎可以保证运行,而CLR创建了一些内部结构来完成这项工作.所以我认为很多句柄都是因为这个 – 你在后台的Task中运行代码,而且肯定是一些同步的内部构造.
另一方面,为什么在发布模式下这不是问题?出于调试目的,正在编译调试模式而不进行编译器优化. Release代码正在优化,你的catch块是空的,所以我认为它永远不会在Release模式下运行 – 你的代码根本就不会抛出,就是这样. 我现在无法检查,但我认为在Release中重现问题的方法是在catch块中添加一些代码: try { throw new Exception("?"); } catch (Exception e) { // log exception here } 更新:我认为您正在测量的不是您的应用程序的句柄数(ConsoleApplication2.exe),而是为您自己运行的VS(ConsoleApplication2.vshost.exe)创建的.所以这只是关于Visual Studio. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |