简体   繁体   中英

C# multi-threading in RFID readers

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 slower 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. I just changed my program to create a bgWorker for each reader. I removed my timer. I use a while loop for reading. but still every time I add a new reader and it starts to read tags despite it is working with a new working thread ID but the reading functionality of other readers become slower

public partial class frmMain : Form
{
    public frmMain()
    {
        InitializeComponent();
    }

    private void frmMain_Load(object sender, EventArgs e)
    {
        int count = 9;

        for (int i = 0; i < count; i++)
        {
            RfControl rfc = new RfControl();
            rfc.gTitle.Text = "Device" + Convert.ToString((i + 1));
            
            this.flowLayoutPanel1.Controls.Add(rfc);
        }
    }

    private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
    {
        for(int i=0; i<this.flowLayoutPanel1.Controls.Count; i++)
        {
            RfControl rfc = (RfControl)this.flowLayoutPanel1.Controls[i];
        }
    }
}
 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.bgWorker.RunWorkerAsync();
    }
}

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;
    public BackgroundWorker bgWorker = null;
    public RfReader()
    {
        bgWorker = new BackgroundWorker();
        bgWorker.DoWork += new DoWorkEventHandler(timer_Tick);
    }
    void timer_Tick(object sender, EventArgs e)
    {
        while (true)
        {
            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); // $FF;
            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)
            {
                if (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))//The search is over
            {
                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;
                }
            }
        }
    }
    
}

Use Thread-Class instead of BgWorker and Invoke all UI-Access. Do the Invoke only when you access UI-Elements, do NOT invoke if you do rfid-reader operations. Do never use timers for this kind of work as you already unterstood. If you need more help, just contact me on contact form

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM