4

Mifare スマート カードからデータを読み取る必要があるアプリケーションに取り組んでいます。Mifare リーダーを定期的にチェックし、カードが範囲内にある場合は、そのシリアル番号を読み取り、親フォームに送信するフォームを作成する必要があります。バックグラウンドワーカーにシリアル番号を読み取らせることができましたが、クロススレッド呼び出しエラーが発生するため、フォームを閉じることができません。backGroundWorker が行う作業を監視し、カード ID の読み取りに成功したら停止して子フォームを閉じる方法はありますか? これは、DoWork メソッドで使用しているコードです。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    while (!worker.CancellationPending)
    {
        MifareReader.CommPort = 4;
        MifareReader.PortOpen = true;
        MifareReader.mfAutoMode(true);               
        MifareReader.mfRequest();                
        if (CardID == "0" || CardID == string.Empty)
        {
            MifareReader.mfRequest();
            CardID = MifareReader.mfAnticollision().ToString();
            MifareReader.mfHalt();
        }
        else if (CardID != "0" && CardID != string.Empty)
        {
            MessageBox.Show(ObrnutiID);
            worker.CancelAsync();                    
        }
        MifareCitac.mfHalt();
    }
}

このコードは機能しますが、フォームを手動で閉じる必要があります。メイン スレッドで CardID 変数の値が変更されているかどうかを確認し、変更されている場合はフォームを閉じる方法はありますか。タイマーを使用してこの問題を解決しようとしましたが、そうすると、タイマーがメインフォームスレッドをブロックし、手動で閉じることができません (もちろん、できる必要があります)。この問題を解決する方法を教えてください。

4

5 に答える 5

1

BackgroundWorker.RunWorkerCompleted他の人が述べたように、イベントを実装する方法は次のとおりです。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    bool found = false;
            var worker = sender as BackgroundWorker;
    while (!worker.CancellationPending && !found)
    {
        MifareReader.CommPort = 4;
        MifareReader.PortOpen = true;
        MifareReader.mfAutoMode(true);               
        MifareReader.mfRequest();                
        if (CardID == "0" || CardID == string.Empty)
        {
            MifareReader.mfRequest();
            CardID = MifareReader.mfAnticollision().ToString();
            MifareReader.mfHalt();
        }
        else
        {
            e.Result = ObrnutiID;
            found = true;
            MifareCitac.mfHalt();
        }
    }
    if (worker.CancellationPending)
    {
        e.Cancel = true;
    }
}

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Cancelled)
        {
            // The user canceled the operation.
            MessageBox.Show("Operation was canceled");
        }
        else if (e.Error != null)
        {
            // There was an error during the operation. 
            string msg = String.Format("An error occurred: {0}", e.Error.Message);
            MessageBox.Show(msg);
        }
        else
        {
            // The operation completed normally. 
            string msg = String.Format("Result = {0}", e.Result);
            MessageBox.Show(msg);
        }
        this.Close() // Closes the form.
    }
于 2013-05-27T09:55:55.483 に答える
1

InvokedRequired を確認し、デリゲートを使用して BeginInvoke を試行することで、クロススレッド呼び出しエラーを回避できます。

于 2013-05-27T09:50:14.100 に答える