2016-08-09 19 views
1

従業員のクロックイン/アウトを追跡するためにバックグラウンドでRFIDリーダーを使用する必要があるバンジープロジェクトがあります。フォアグラウンドwinform GUIは、注文、相場などの日常的な取引を処理するため、従業員の出入りを追跡しながら、中断することなくプログラムを使用できるようにする必要があります。私はバックグラウンドワーカー、新しいトレッドと入力グラブを調べました。しかし、私はうまくいくものを見つけることができないようです。 RFIDリーダはキーボードとして機能し、その名前を得ることができます。 Raw Inputバックグラウンド処理によるUSB RFIDリーダー入力の使用

RFID詳細を使用して:RFID Reader Details

を明確にするため、ユーザは、RFIDリーダからの入力は、バックグラウンドリストに記録されなければならないしながら、中断することなくプログラム(複数形)を使用することができなければなりません。

私はバックグラウンドワーカーには新しく、マルチスレッドと入力グラブを行っていますので、いくつかの詳細なヘルプに感謝します。また、私の側から詳細が必要かどうか質問してください。

+0

あなたは、いくつかのコードを持っていますか?コードなしでは、これは広すぎるでしょう... –

+0

あなたのデバイスでC#のいくつかのRFIDを読み終えましたか?その後、すでに試したコードを投稿してください。 – BoeseB

答えて

0

マルチスレッドはあまり簡単ではありません。 BackgroundWorkerはGUI上でやや簡単ですが、バックグラウンドタスクからGUIにアクセスするのはまだ難しいです。最初にTask/Awaitを試してみませんか?これにより、マルチスレッドが回避され、2つのタスクを実行できます。

+0

彼はasync/awaitをサポートする.NET 4.5を使用していると仮定します。以前の.NETバージョンを使用している場合、AsyncBridgeのようなライブラリが必要です。 Async/awaitとTaskが並列プログラミングを簡素化しても、まだマルチスレッド化は不可能です。マルチスレッドを使用してRFIDリーダーをポーリングする前に、使用しているUSBライブラリがこれをサポートしている場合、USBデバイスの受信イベントに反応しようと提案します。 – BoeseB

+1

真。私は古いバージョンの.Netには行きません。タスクは私のコンセプトを取得するのに時間がかかりましたが、実際のマルチスレッドよりはるかに優れています。 – Roland

1

ここでは、NordicID Sampoには、データを読み取るスレッドを起動するAPIが付属しています。あなたは、そのスレッドによって追加されたバッファからデータを読み込むタスクを作成することでそれを構築することができます。その後、フォームにそのデータを渡すか、それを電子メールで送信することができます。

スキャナにはおそらく同様のメカニズムがあります。

例: 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を保存し、4.5でGUIのナットを更新するために使用します。ConfigureWait – Laurijssen

1

あなたがLibUsbDotNet を使用している場合、あなたはDataReceivedEventに反応することができます。したがって、新しいデータをポーリングしながらブロックすることは避けてください。ポーリングを選択した場合、@Servéはすでにメインスレッドをブロックしないように別のタスクに送る方法を示しました。

ここでは、DataReceivedEventの推奨される解決策を示します。

は、USBデバイスを初期化します。

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; 

はEventHandlerの定義:

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"); 
} 
関連する問題