为什么我得到这个“ 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","");
}
}
答案 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