public static extern int SCardGetStatusChange(IntPtr hContext, int value_Timeout, ref SCARD_READERSTATE ReaderState, uint ReaderCount);
private async Task CardDetectionLoop(CancellationToken token) { await Task.Delay(1, token) .ConfigureAwait(false); // resume on threadpool thread while (!token.IsCancellationRequested) { try { var currentState = new SCARD_READERSTATE { RdrName = Name, RdrCurrState = Constants.SCARD_STATE_UNAWARE, RdrEventState = 0 }; const int readerCount = 1; const int timeout = 0; var retval = SafeNativeMethods.SCardGetStatusChange(hContext, timeout, ref currentState, readerCount); if (retval == 0 && currentState.ATRLength > 0) { // Card inserted if (!cardInserted) { cardInserted = true; OnDisconnect(); // clean up if needed var card = new SmartCard(hContext, Name, currentState.ATRValue); if (Interlocked.CompareExchange(ref currentCard, card, null) == null) { // card was not inserted, now it is // Raise on another thread to not block this loop var evt = CardAdded; if (evt != null) { Task.Run(() => evt(this, new CardAddedEventArgs(card))); } } } } else { // Card removed if (cardInserted) { cardInserted = false; // HACK: Let our tranceive method know it's gone for one buggy reader // bug in the 5427 CK reader if (Name.Contains("5427 CK")) { SmartCardConnectionExtension.IsFirstConnection = false; } OnDisconnect(); } } await Task.Delay(250, token); } catch (Exception ex) { Debug.WriteLine("Exception from card monitor thread: " + ex); } } }