I've written a program which could connect to several RFID Reader and start to detect tags simultaneously. But because all of them are working on UI-Thread (Main Thread) my both UI and reading function become too slow every time I add a new reader...
I need to create a new thread for each reader and let that reader works with the new worker thread.
But I don't know where have I import the new Thread() function in my c# program.
I have a windows form timer for reading tags.
What I have tried:
void timer_Tick(object sender, EventArgs e)
{
Reader();
}
Public void Reader(){
int fCmdRet = StaticClassReaderB.Inventory_G2(ref fComAdr, Qvalue, Session, AdrTID, LenTID, TIDFlag, EPC, ref Totallen, ref CardNum, frmcomportindex);
if ((fCmdRet == 1) | (fCmdRet == 2) | (fCmdRet == 3) | (fCmdRet == 4) | (fCmdRet == 0xFB))
{
if (CardNum == 0)
{
return;
}
byte[] daw = new byte[Totallen];
Array.Copy(EPC, daw, Totallen);
temps = ByteArrayToHexString(daw);
if (temps == "") return;
m = 0;
for (CardIndex = 0; CardIndex < CardNum; CardIndex++)
{
EPClen = daw[m];
string TID = temps.Substring(m * 2 + 2, EPClen * 2);
lastEPC = TID;
m = m + EPClen + 2;
value = TID;
}
}
I have two class as below:
public partial class RfControl : UserControl
{
RfReader rf = new RfReader();
public RfControl()
{
InitializeComponent();
}
private void btnOpen_Click(object sender, EventArgs e)
{
try
{
rf.type = this.cbType.Text;
rf.IPAddr = this.txtIP.Text.Trim();
rf.port = Convert.ToInt32(this.txtPort.Text.Trim());
rf.OnScan += new EventHandler(rf_OnScan);
rf.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
void rf_OnScan(object sender, EventArgs e)
{
try
{
string value = ((RfReader)sender).value;
if (this.lstContent.Items.IndexOf(value) == -1)
{
this.lstContent.Items.Add(value);
}
this.txtCount.Text = this.lstContent.Items.Count.ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnClose_Click(object sender, EventArgs e)
{
try
{
rf.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnClear_Click(object sender, EventArgs e)
{
this.lstContent.Items.Clear();
this.txtCount.Text = "0";
}
private void btnQuery_Click(object sender, EventArgs e)
{
rf.timer.Enabled = !rf.timer.Enabled;
}
}
class RfReader
{
Api api = new Api();
ArrayList idList = new ArrayList();
byte[,] tagData = null;
byte v1 = 0;
byte v2 = 0;
int status = 0;
int iMembankMask = 0, iStartAddr_Reserve = 0, iStartAddr_EPC, iStartAddr_TID, iStartAddr_User, reserveLen, epcLen, tidLen, userLen, readCnt, wordLen = 0;
public int frmcomportindex;
public byte readerAddr = 0xff;
private byte fComAdr = 0xff;
public int port = -1, openresult = 0;
public string IPAddr = "";
public string type = "";
public string value = "";
public string X = "";
public string Y = "";
public string Name = "";
public System.Windows.Forms.Timer timer = null;
private static object _locker = new object();
public RfReader()
{
timer = new System.Windows.Forms.Timer();
timer.Interval = 1;
timer.Tick += new EventHandler(timer_Tick);
}
void timer_Tick(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem((object state) => { Reader(); });
}
public void Open()
{
if (type == "AR")
{
if (!api.isNetWorkConnect(IPAddr))
{
api.TcpCloseConnect();
throw new Exception(IPAddr + " Open failed");
}
status = api.TcpConnectReader(IPAddr, Convert.ToInt32(port));
if (status != ReaderApi.Api.SUCCESS_RETURN)
{
api.TcpCloseConnect();
throw new Exception(IPAddr + " Open failed");
}
status = api.GetFirmwareVersion(255, ref v1, ref v2);
if (status != ReaderApi.Api.SUCCESS_RETURN)
{
api.TcpCloseConnect();
throw new Exception(IPAddr + " Open failed");
}
iStartAddr_Reserve = iStartAddr_EPC = iStartAddr_TID = iStartAddr_User = reserveLen = epcLen = tidLen = userLen = readCnt = 0;
iMembankMask = 0;
wordLen = 6;
iMembankMask += 1;
wordLen += 4;
iStartAddr_Reserve = 0;
reserveLen = 4;
iMembankMask += 2;
wordLen += 8;
iStartAddr_EPC = 0;
epcLen = 8;
iMembankMask += 4;
wordLen += 12;
iStartAddr_TID = 0;
tidLen = 12;
iMembankMask += 8;
wordLen += 10;
iStartAddr_User = 0;
userLen = 10;
tagData = new byte[500, wordLen * 4];
idList.Clear();
throw new Exception(IPAddr + " Open Success");
}
else if (type == "ZK")
{
byte readerAddr = Convert.ToByte("FF", 16); openresult = StaticClassReaderB.OpenNetPort(port, IPAddr, ref fComAdr, ref frmcomportindex);
if ((openresult == 0x35) || (openresult == 0x30))
{
StaticClassReaderB.CloseNetPort(frmcomportindex);
throw new Exception(IPAddr + " Open failed");
}
if (openresult == 0)
{
throw new Exception(IPAddr + " Open Success");
}
}
}
public void Close()
{
if (type == "AR")
{
api.TcpCloseConnect();
}
else if (type == "ZK")
{
StaticClassReaderB.CloseNetPort(frmcomportindex);
frmcomportindex = -1;
}
}
public event EventHandler OnScan;
public void Reader()
{
if (type == "AR")
{
readCnt = 0;
int getCount = 0;
string strTemp = "", strAnteNo = "", strEPC = "", strSubEPC = "", strTID = "", strReserve = "", strUser = "";
status = api.Gen2MultiTagRead(255, (byte)iMembankMask, (byte)iStartAddr_Reserve, (byte)reserveLen, (byte)iStartAddr_EPC, (byte)epcLen, (byte)iStartAddr_TID, (byte)tidLen, (byte)iStartAddr_User, (byte)userLen, ref readCnt);
if (status == Api.SUCCESS_RETURN && readCnt > 0)
{
if (api.GetTagData(255, ref tagData, readCnt, ref getCount) == Api.SUCCESS_RETURN && getCount > 0)
{
for (int loop = 0; loop < getCount; loop++)
{
strTemp = "";
for (int j = 1; j <= (int)tagData[loop, 0]; j++)
strTemp += string.Format("{0:X2}", tagData[loop, j]);
strEPC = strTemp.Substring(2, 24);
strReserve = strTemp.Substring(26, reserveLen * 4);
strSubEPC = strTemp.Substring(26 + reserveLen * 4, epcLen * 4);
value = strTemp.Substring((26 + reserveLen * 4 + epcLen * 4) + 8, 16);
strUser = strTemp.Substring(26 + reserveLen * 4 + epcLen * 4 + tidLen * 4, userLen * 4);
OnScan(this, new EventArgs());
}
}
}
}
else if (type == "ZK")
{
int CardNum = 0, Totallen = 0, EPClen, m, CardIndex;
byte[] EPC = new byte[5000];
string temps, s;
byte AdrTID = 0, LenTID = 0, TIDFlag = 0;
AdrTID = 2;
LenTID = 4;
TIDFlag = 1;
byte Qvalue = 4;
byte Session = 0;
string lastEPC = "";
int fCmdRet = StaticClassReaderB.Inventory_G2(ref fComAdr, Qvalue, Session, AdrTID, LenTID, TIDFlag, EPC, ref Totallen, ref CardNum, frmcomportindex);
if ((fCmdRet == 1) | (fCmdRet == 2) | (fCmdRet == 3) | (fCmdRet == 4) | (fCmdRet == 0xFB)) {
if (CardNum == 0)
{
return;
}
byte[] daw = new byte[Totallen];
Array.Copy(EPC, daw, Totallen);
temps = ByteArrayToHexString(daw);
if (temps == "") return;
m = 0;
for (CardIndex = 0; CardIndex < CardNum; CardIndex++)
{
EPClen = daw[m];
string TID = temps.Substring(m * 2 + 2, EPClen * 2);
lastEPC = TID;
m = m + EPClen + 2;
value = TID;
}
}
}
}
i jsut added new functions as below instead of that timer :
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
while (true)
{
rf.Reader();
}
}
private void btnQuery_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}