h4kbas / nfc-reader

A simple library that provides to use rfid card readers.
MIT License
128 stars 44 forks source link

Worker never stops. #12

Open k0nagy opened 3 years ago

k0nagy commented 3 years ago

Hi!

Thank you for your code it is very usefull.

The worker never returns from its thread. Here is a fix:

` BackgroundWorker worker = sender as BackgroundWorker;

    while (!e.Cancel)
    {
        int nErrCode = Card.SCardGetStatusChange(hContext, 1000, ref states[0], 1);

        if(worker.CancellationPending)
        {
            e.Cancel = true;
            return;
        }

        if (nErrCode == Card.SCARD_E_SERVICE_STOPPED)
        {
            DeviceDisconnected();
            e.Cancel = true;
            return;
        }

        //Check if the state changed from the last time.
        if ((this.states[0].RdrEventState & 2) == 2)`

Other fix: ` public void Disconnect() { if (connActive) { retCode = Card.SCardDisconnect(hCard, Card.SCARD_UNPOWER_CARD); if (retCode == 0) { _worker?.CancelAsync(); connActive = false; } } //retCode = Card.SCardReleaseContext(hCard); }

public void Watch() { this.RdrState = new Card.SCARD_READERSTATE(); readername = GetReadersList()[0]; this.RdrState.RdrName = readername;

    states = new Card.SCARD_READERSTATE[1];
    states[0] = new Card.SCARD_READERSTATE();
    states[0].RdrName = readername;
    states[0].UserData = 0;
    states[0].RdrCurrState = Card.SCARD_STATE_EMPTY;
    states[0].RdrEventState = 0;
    states[0].ATRLength = 0;
    states[0].ATRValue = null;
    _worker = new BackgroundWorker
    {
        WorkerSupportsCancellation = true
    };

    _worker.DoWork += WaitChangeStatus;
    _worker.RunWorkerCompleted += _worker_RunWorkerCompleted;
    _worker.RunWorkerAsync();
}

private void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    DisposeWorker();
}

public void Dispose()
{
    Disconnect();
    DisposeWorker();
}

private void DisposeWorker()
{
    System.Diagnostics.Debug.WriteLine("DisposeWorker");
    if (_worker != null)
    {
        if(_worker.IsBusy)
        {
            _worker.CancelAsync();
            return;
        }

        _worker.DoWork -= WaitChangeStatus;
        _worker.RunWorkerCompleted -= _worker_RunWorkerCompleted;
        _worker.Dispose();
        _worker = null;
    }
}

`

You need an implement: public class NFCReader : IDisposable

Kind regards, Karoly

h4kbas commented 3 years ago

Thank you, if you can send a pull request, I can analyze it and merge it if everything works correctly

k0nagy commented 3 years ago

Hi,

I tried, but I don't have right, I get a 403 error code. I'd attached here the cs file. NFCReader.zip

h4kbas commented 3 years ago

Oh why is it? Did you fork and did your fix and create a PR?