如何解决如果在C#应用程序中的线程上执行,则SCardControl的速度会降低5倍
我正在使用Visual Studio 2019构建一个C#Win Form应用程序,该应用程序旨在与SmartCard(ACR 122U)通信。
简而言之:我正在使用的标签类型是被动标签,读者无法识别。使用这些标签的唯一方法是将直接命令发送到读取器内部的芯片。
我使用winscard.dll设法做到了。
我正在尝试备份标签:该过程必须读取和存储128个块(因此将调用128个SCardControl)。
如果我在UI线程中执行此操作,它的工作原理就像一个魅力(最长5秒,过程中该过程占用30MB的内存)。 但是,如果我尝试在后台线程中执行此操作,则将花费很多时间(至少25秒,在此过程中需要150MB的内存用于该过程)。
为什么会这样?
编辑:
这是线程的一些代码
//All the DllImport directives:
[DllImport("winscard.dll")]
public static extern int SCardEstablishContext(uint dwScope,IntPtr notUsed1,IntPtr notUsed2,out IntPtr phContext);
[DllImport("winscard.dll",EntryPoint = "SCardListReadersA",CharSet = CharSet.Ansi)]
public static extern int SCardListReaders(IntPtr hContext,byte[] mszGroups,byte[] mszReaders,ref UInt32 pcchReaders);
//... Other working method delcarations
//Declaration of the "slow" method SCardControl
[DllImport("winscard.dll")]
public static extern int SCardControl(IntPtr hCard,int dwControlCode,byte[] lpInBuffer,uint cbInBufferSize,byte[] lpOutBuffer,ref uint cbOutBufferSize,ref int lpBytesReturned);
//... Other declarations.
private void btnBackup_Click(object sender,EventArgs e)
{
Thread t = new Thread(bgWorker);
t.Start();
//bgWorker();
}
public void bgWorker() {
int res;
uint SystemScope = 2; //From the documentation. Tried both 1 and 2 (User scope and System Scope)
uint readerNum = 0;
uint controlMode = 3; //Using SCARD_SHARE_DIRECT as control mode in order to communicate with the reader
uint protocolToUse = 0; //Using SCARD_PROTOCOL_UNDEFINED as protocol (must use it in order to use SCARD_SHARE_DIRECT)
int EscapeCode = 3225264; //Suggested by ACR 122 U: Escape code in order to send commands to the reader,computes as SCARD_CTL_CODE(3500) in C.
string ReadBlockCmd = "FF000000..." //Standard read command in hex for the tag from dtatasheet
IntPtr context = IntPtr.Zero;
IntPtr simulatedCard = IntPtr.Zero;
IntPtr protocolEstablished = IntPtr.Zero;
byte[] readerStream;
string[] readerList;
byte[] retStream = new byte[1000];
uint sizeRetStream = 0;
int sizeResponse = 0;
List<string> cardBlocks = new List<string>();
//NOTE: "res" is always = 0 when everything works. I cutted off the parts where i check the value of "res".
//Establishing context
res = SCardEstablishContext(SystemScope,IntPtr.Zero,out context);
//Getting the reader list (the return is in "readerStream",with a multistring value)
res = SCardListReaders(context,null,ref readerNum);
readerStream = new byte[readerNum];
res = SCardListReaders(context,readerStream,ref readerNum);
readerList = Encoding.ASCII.GetString(readerStream).Split('\0');
//Connect to the reader
res = SCardConnect(context,readerList[0],controlMode,protocolToUse,ref simulatedCard,ref protocolEstablished);
/*
* Some calls to SCardControl to configure the reader in order to work with my tags
*/
//Backup procedure
for(int i = 0; i < 128; i++)
{
SCardControl(simulatedCard,EscapeCode,HexStrToByteArray(ReadBlockCmd + i.ToString("X2")),(uint)ReadBlockCmd.Length / 2 + 1,retStream,ref sizeRetStream,ref sizeResponse);
cardBlocks.Add(ByteArrayToHexStr(retStream,sizeResponse));
}
//Here it supposed to do the backup on file,but i removed it in order to limit the IO ops
}
如果注释线程启动部分并取消注释对bgWorker()的调用,则过程将持续2.1秒。 如果保持这种状态(使用线程),则该过程将持续20秒钟以上(无论是在调试模式下,在发行版中,在Visual Studio中还是在外部)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。