2017-06-13 15 views
0

私はRFIDをシリアルポートで読み取るアプリケーションを開発しています。 timerを使用して、ユーザーがボタンをクリックするまでスキャンを続けます。
スキャナが新しいRFIDを見つけたら、RFIDが既にDataGridViewに入っていれば、DataGridViewに情報を挿入します。緑の色で行を塗りつぶし、DataGridViewのRFIDがスキャナの範囲になくなったら、白色である。
私の問題は、少しの時間が過ぎればRFIDが2回以上挿入されるということです。
私はそれがタイマーのスレッドのためだと思ったので、私はlockを入れましたが、200msよりも小さな時間でスキャンしようとすると、まだ問題が発生しています。DataGridViewにデータを挿入する際に行が重複しないようにするにはどうすればよいですか?

コードを改善する方法はありますか?

void tmrRepeatedScan_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
     { 
      try 
      { 
       lock (thisLock) 
       { 
        var detectedTags = serialPort.Scan(true, false, true, false); 

        foreach (var tag in detectedTags) 
        { 
         bool tagFound = false; 
         string TID = Regex.Replace(Conversions.ByteToHexadecimal(tag.GetTagId()), "(.{2})(?!$)", "$0-"); 
         string EPC = Regex.Replace(Conversions.ByteToHexadecimal(tag.GetEpc()), "(.{2})(?!$)", "$0-"); 

         if (!tagsReaded.Contains(TID)) 
         { 
          tagsReaded.Add(TID); 
         } 

         foreach (DataGridViewRow row in dgvTags.Rows) 
         { 
          if (row.Cells[0].Value.ToString().Equals(TID)) 
          { 
           row.DefaultCellStyle.BackColor = Color.LightGreen; 
           tagFound = true; 
           break; 
          } 
         } 

         if (!tagFound) 
         { 
          dgvTags.BeginInvoke(new InvokeDelegate(() => AddRow(TID, EPC))); 
         } 
        } 
       } 

       foreach (DataGridViewRow row in dgvTags.Rows) 
       { 
        if (!tagsReaded.Contains(row.Cells[0].Value.ToString())) 
        { 
         row.DefaultCellStyle.BackColor = Color.White; 
        } 
       } 
      } 
      catch (Exception ex) 
      { 
       foreach (DataGridViewRow row in dgvTags.Rows) 
       { 
        row.DefaultCellStyle.BackColor = Color.White; 
       } 
      } 
     } 

私の英語はあまり良くありません。

+0

BeginInvokeは 'async'操作です。代わりにInvokeを使用して、重複の問題を解決するかどうかを確認してください。 – JohanP

+0

それはkyouより重複の問題を解決します! –

+0

しかし、50msのような小さな経過時間を設定すると、それは遅すぎるようになります。 –

答えて

0

BeginInvokeに戻すことができますが、AddRowを実行する前に、あなたのタグがtagsReadedに存在するかどうかを確認する必要があります。これを試してください:

void tmrRepeatedScan_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
{ 
     try 
     { 
      lock (thisLock) 
      { 
       var detectedTags = serialPort.Scan(true, false, true, false); 

       foreach (var tag in detectedTags) 
       { 
        bool tagFound = false; 
        string TID = Regex.Replace(Conversions.ByteToHexadecimal(tag.GetTagId()), "(.{2})(?!$)", "$0-"); 
        string EPC = Regex.Replace(Conversions.ByteToHexadecimal(tag.GetEpc()), "(.{2})(?!$)", "$0-"); 

        foreach (DataGridViewRow row in dgvTags.Rows) 
        { 
         if (row.Cells[0].Value.ToString().Equals(TID)) 
         { 
          row.DefaultCellStyle.BackColor = Color.LightGreen; 
          tagFound = true; 
          break; 
         } 
        } 

        bool isNewTag = !tagsReaded.Contains(TID); 

        if (!tagFound && isNewTag) 
        { 
         dgvTags.BeginInvoke(new InvokeDelegate(() => AddRow(TID, EPC))); 
        } 

        if (newTag) 
        { 
         tagsReaded.Add(TID); 
        } 
       } 
      } 

      foreach (DataGridViewRow row in dgvTags.Rows) 
      { 
       if (!tagsReaded.Contains(row.Cells[0].Value.ToString())) 
       { 
        row.DefaultCellStyle.BackColor = Color.White; 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      foreach (DataGridViewRow row in dgvTags.Rows) 
      { 
       row.DefaultCellStyle.BackColor = Color.White; 
      } 
     } 
} 
関連する問題