2016-08-09 3 views
1

필자는 Employee Clock-in/Out을 추적하기 위해 백그라운드에서 RFID 리더를 사용해야하는 대표 프로젝트를 가지고 있습니다. foreground winform GUI는 Orders, quotes 등과 같은 일상적인 트랜잭션을 처리하기 때문에 끊임없이 프로그램을 사용할 수 있어야합니다. 동시에 직원의 왕래를 추적 할 수 있어야합니다. 나는 배경 노동자들과 일종의 새로운 트레드와 투입물을 들여다 보았다. 그러나 나는 작동할만한 것을 찾을 수없는 것 같습니다. RFID 판독기는 키보드 역할을하며 그 이름을 알 수 있습니다. Raw Input백그라운드 처리로 USB RFID 리더 입력 사용하기

RFID 정보 사용 : RFID Reader Details

명확히하기를, 사용자는 RFID 리더로부터 어떤 입력이 배경 목록에 기록되어야하는 동안 중단없이 프로그램 (복수 형태)를 사용 할 수 있어야합니다.

저는 배경 작업자가 새로운데, 멀티 스레딩 및 입력 잡기 때문에 자세한 도움을 주시면 감사하겠습니다. 또한 제 쪽에서 자세한 내용이 필요한지 물어보십시오.

+0

당신이 몇 가지 코드를 가지고 있습니까를? 코드가 없으면 이것은 너무 광범위 할 것입니다 ... –

+0

C#의 일부 RFID를 이미 장치에서 읽었습니까? 그런 다음 이미 시도한 코드를 게시하십시오. – BoeseB

답변

0

멀티 스레드는 그리 쉽지 않습니다. BackgroundWorker는 GUI에서 다소 쉽지만 백그라운드 작업 내에서 GUI에 액세스하는 것은 여전히 ​​어렵습니다. Task/Await으로 먼저 시도해 보지 않겠습니까? 이렇게하면 멀티 스레딩을 피할 수 있으며 두 가지 작업을 계속 실행할 수 있습니다.

+0

그는 async/await를 지원하는 .NET 4.5를 사용하고 있습니다. 이전 .NET 버전을 사용하고 있다면 AsyncBridge와 같은 라이브러리가 필요합니다. Async/await and Task가 병렬 프로그래밍을 간소화하더라도 여전히 멀티 스레딩이 가능합니다. 멀티 쓰레딩을 사용하여 RFID 리더를 폴링하기 전에 사용 된 USB 라이브러리가 지원하는 경우 USB 장치의 수신 이벤트에 반응하려고 제안합니다. – BoeseB

+1

참. 나는 .Net의 옛 버전을 가지고 가지 않을 것이다.태스크는 개념을 이해하는 데 다소 시간이 걸렸지 만, 이제는 실제 멀티 스레딩보다 훨씬 좋았습니다. – Roland

1

RFID 판독기 여기 NordicID Sampo에는 데이터를 읽는 스레드를 시작하는 API가 있습니다. 해당 스레드가 추가 한 버퍼에서 데이터를 읽는 Task를 작성하여이를 빌드 할 수 있습니다. 그런 다음 해당 데이터를 양식에 전달하거나 이메일로 보낼 수 있습니다.

스캐너에는 아마도 비슷한 메커니즘이 있습니다.

예 : StartStreaming은 장치 API를 둘러싼 래퍼이며 장치의 데이터를 읽는 스레드를 시작합니다. 자신의 작업을 주기적으로 데이터에 대한 검사를 발사

class RFIDReader : IDisposable 
    { 
     public void StartStreaming() 
     { 
      if (RFID_ConnectSerialPort(mAPIHandle, 4, 115200) == 0 || RFID_ConnectAutoUSB(mAPIHandle) == 0) 
      { 
       RFID_StartInventoryStreaming(
        (value, antenna) => { 
         mAntennas[antenna].Add(value); 
        }); 
      } 
     } 
/////// MORE FUNCTIONS 
    } 

클라이언트 코드 :

static void Main(string[] args) 
{ 
    Action a = new Action(() => 
    { 
     using (RFIDReader scanner = new RFIDReader()) 
     { 
      scanner.StartStreaming(); 

      while (true) 
      { 
       foreach (string s in scanner.GetData(0)) 
       { 
        WriteLine($"antenna0: {s}"); 
       } 
       Thread.Sleep(1000); 
      } 
     } 
    }); 
    Task t = Task.Factory.StartNew(a); 

    t.Wait(); 
} 
+1

교착 상태를 피하기 위해 [Task.ConfigureAwait (false)] 사용을 고려하십시오 (https://blog.ciber.no/2014/05/19/using-task-configureawaitfalse-to-prevent-deadlocks-in-async-code/) . – BoeseB

+0

그런 다음 .NET 4.5, 생산 코드에서 SynchronizationContext를 저장하고 GUI에서 너트를 업데이트하는 데 사용합니다 4.5 예를 들어 ConfigureWait – Laurijssen

1

당신이 LibUsbDotNet 를 사용하는 경우 당신은 DataReceivedEvent에 반응 할 수있다. 따라서 새로운 데이터를 폴링하는 동안 블로킹을 피할 수 있습니다. 폴링 aproach @ Servée를 선택했다면 @ Servé는 이미 주 스레드를 차단하지 않도록 다른 작업으로 보내는 방법을 보여주었습니다.

DataReceivedEvent와 함께 제안 된 솔루션이 있습니다.

IUsbDevice wholeUsbDevice = PhysicalLibUSBDevice as IUsbDevice; 
    if (!ReferenceEquals(wholeUsbDevice, null)) 
    { 
     // This is a "whole" USB device. Before it can be used, 
     // the desired configuration and interface must be selected. 

     // Select config #1 
     wholeUsbDevice.SetConfiguration(1); 

     // Claim interface #0. 
     wholeUsbDevice.ClaimInterface(0); 
    } 


    // Create the reader and writer streams 
    _libUsbReader = PhysicalLibUSBDevice.OpenEndpointReader(LibUsbDotNet.Main.ReadEndpointID.Ep01); 
    _libUsbWriter = PhysicalLibUSBDevice.OpenEndpointWriter(LibUsbDotNet.Main.WriteEndpointID.Ep02); 

    _libUsbReader.DataReceived += OnDataReceived; 
    _libUsbReader.DataReceivedEnabled = true; 
    _libUsbReader.ReadThreadPriority = System.Threading.ThreadPriority.Highest; 
    _libUsbReader.ReadBufferSize = 32; 

이벤트 핸들러 정의 :

은 USB 장치를 초기화

private void OnDataReceived(object sender, EndpointDataEventArgs e) 
{ 
    //Use the Buffer and Count Properties of the EventArgs to get the received data   
    Console.WriteLine("Data received"); 
} 
관련 문제