执行一小时后System.OutOfMemoryException

时间:2014-10-11 12:15:46

标签: c# c#-4.0

为什么我得到这个“ System.OutOfMemoryException

此代码提供从智能卡读卡器读取智能卡的服务,并将结果放入任何应用程序中关注的文本框中。当它运行(超过60分钟)时,我丢失了错误。在我的情况下发生了什么?

请咨询

class Program
    {
        static bool infinity = true;
        static WinSCard sCard;

        public static void Main(string[] args)
        {
            try
            {
                sCard = new WinSCard();

                while (infinity) {

                    sCard.EstablishContext();                   //establis smart card reader resourete manager
                    sCard.ListReaders();                        //get list of smart card reader

                    string readerName = sCard.ReaderNames[0];   //the first smart card reader in the list

                    sCard.WaitForCardPresent(readerName);       //block execution until smart card was attached to the reader
                    sCard.Connect(readerName);                  //connect to a smart card

//                  Console.WriteLine( "ATR: 0x" + sCard.AtrString );


                    byte[] cmdApdu = { 0xFF, 0xCA, 0x00, 0x00, 00 };    // get card UID ...
                    byte[] respApdu = new byte[6];
                    int respLength = respApdu.Length;

                    //submit command to smart card and get a return result
                    sCard.Transmit(cmdApdu, cmdApdu.Length, respApdu, ref respLength);

                    //Convert Bute[] to HexString and finally Integer
                    int num = Int32.Parse(ByteArrayToString(respApdu, respLength), System.Globalization.NumberStyles.HexNumber);
                    Console.WriteLine("GET CARD UID ==> " + num);

                    //Send Result to any input that currently got focus
                    SendKeys.SendWait(num.ToString());

                    sCard.WaitForCardRemoval(readerName);   //block execution until smart card was removed to the reader
                    sCard.Disconnect();                     //terminated connection to a smart card
                    sCard.ReleaseContext();                 //freely any resource allocated under the context
                }
            }
            catch (WinSCardException ex)
            {
                Console.WriteLine( ex.WinSCardFunctionName + " 0x" + ex.Status.ToString( "X08" ) + " " + ex.Message );
            }
            finally
            {
                Console.WriteLine("Please press any key...");
                Console.ReadLine();
            }
        }

        public static string ByteArrayToString(byte[] ba, int length)
        {
            StringBuilder hex = new StringBuilder(length * 2);
            foreach (byte b in ba)
                hex.AppendFormat("{0:x2}", b);
            return hex.ToString().Replace("9000","");
        }
    }

3 个答案:

答案 0 :(得分:1)

您的代码中是否存在实现IDisposable的任何类,并且您没有处置它们,或者是它们的任何PInvoke调用,它们需要额外的调用来清理它们分配的任何内存。

答案 1 :(得分:0)

我的猜测是sCard.ListReaders()导致你的问题,所以我会更详细地分析那里的代码。我假设有一些内部集合从未清理过,而你的sCard是静态变量。您可以调试/编写单元测试或使用内存分析工具(如ANTS Memory Profiler)(创建初始快照,然后在10分钟后比较哪个实例消耗您的内存)

答案 2 :(得分:0)

在循环中重用WinSCard对象可能会有所帮助。只需在每个开头创建一个新实例。 而且您不需要将此对象放入静态成员,将其用作局部变量。

    public static void Main(string[] args)
    {
        try
        {
            while (infinity) {

                var sCard = new WinSCard();

                sCard.EstablishContext();                   //establis smart card reader resourete manager
                sCard.ListReaders();                        //get list of smart card reader

如果WinSCard实现IDisposable将其包装在using语句中,以确保释放可能不再使用的资源:

                using(var sCard = new WinSCard())
                {
                    sCard.EstablishContext();                   //establis smart card reader resourete manager
                    sCard.ListReaders();                        //get list of smart card reader