加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 在任务中抛出异常时处理泄漏

发布时间:2020-12-15 20:56:05 所属栏目:百科 来源:网络整理
导读:我试图理解应用程序中发生的一个非常奇怪的句柄泄漏. 我已设法在以下代码中隔离问题: using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace ConsoleApplica
我试图理解应用程序中发生的一个非常奇怪的句柄泄漏.
我已设法在以下代码中隔离问题:

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秒就足以达到这个值)

Task Manager screen shot

但是,删除“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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读