2

GPSモデムを介してcomportを介して次のコードを使用してSMSを送信しています

Thread thread = null;
private void btnsend_Click(object sender, EventArgs e)
    {
        if (thread == null)
        {                
            thread = new Thread(SendSms);
            thread.IsBackground = true;
            thread.Start();
        }
    }
    private void Update(int i)
    {
        if(InvokeRequired)
        {
            this.BeginInvoke(new Action<int>(Update), new Object[] {i});
            return;
        }
        using (var sp = new SerialPort("COM6"))
        {
            sp.Open();
            sp.WriteLine("AT" + Environment.NewLine);
            sp.WriteLine("AT+CMGF=1" + Environment.NewLine);
            sp.WriteLine("AT+CMGS=\"" + dt2.Rows[i]["PhoneNo"] + "\"" + Environment.NewLine);
            sp.WriteLine(tbsms.Text + (char)26);
            if (sp.BytesToRead > 0)
            {
                tbsentto.Text = i + 1 + " of " + dt2.Rows.Count;
            }
        }
    }
    private void SendSms()
    {
        for(int i = 0; i < dt2.Rows.Count; i++)
        {
            Update(i);
            Thread.Sleep(5000);
        }
        thread = null;
    }

私の質問は次のとおりです。ユーザーが btnsend を押して他の受信者に SMS を送信できないように、スレッドが進行するまで btnsend を無効にしておくにはどうすればよいですか?

4

3 に答える 3

3

私自身のプロジェクトの1つで同様の問題がありました。

私が行った解決策は次のとおりです。

フォームの各ボタンのバックグラウンド ワーカーを作成したときに、それらに DoWork および RunWorkerCompleted ワーカー スレッドを割り当てました。

次に、ボタンがクリックされたときにトリガーされるスレッドに、ワーカー スレッドが既に実行されていないことを確認するためのチェックも含めました (ボタン自体がトリガーしたスレッドを含む)。

だから私のコードは次のようになりました:

private void XYZ_button_Click(object sender, EventArgs e)
{
    /* Check no background workers are already running */
    if ((XYZ_backgroundworker.IsBusy != true) &&
        (PQR_backgroundworker.IsBusy != true)) /* etc, etc for any other background
        workers you might have */
    {
        XYZ.RunWorkerAsync();
    }
}

private void XYZ_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error != null) MessageBox.Show("Error: " + e.Error.Message);
    else if (e.Cancelled == true) MessageBox.Show("Canceled!");
}

private void XYZ_DoWork(object sender, DoWorkEventArgs e)
{
    //Your code here
}

バックグラウンド ワーカーの作成方法を知っていることを前提としていますが、そうでない場合は、フォーム デザイン ページのツールボックスで見つけることができます。リストからそれらを選択し、割り当てたいボタンをクリックするだけです。あとは、バックグラウンド ワーカーのイベント プロパティに移動し、適切なワーカー スレッドを割り当てるだけです。

特定のケースでは、バックグラウンド ワーカー スレッドを作成し、その内容をスレッドに移動する必要がありbtnsend_ClickますDoWork。次に、上記で使用した形式に従います。

お役に立てれば :)

于 2012-04-05T09:01:10.930 に答える
1

スレッドのアクションの最後でボタンを有効にする関数を呼び出すことができます。これは簡単な方法の 1 つです。ただし、これをより一般的に処理したい場合は、Thread クラスにラッパーを記述するか、Thread クラスから新しいクラスを派生させることができます。新しいクラスでは、スレッドのアクション完了時に発生するイベントを作成できます。

更新:(Hans Passantが私に思い出させた後)

BackGroundWorkerを使用できます。上で説明した方法と同じです。アクションが完了した後に発生するイベント WorkerCompleted に登録します。ここに小さな例があります

于 2012-04-05T07:14:02.020 に答える
1

ジョージ・ポッターの助けを借りて、私の質問の解決策を見つけました。どうもありがとう

private void btnsend_Click(object sender, EventArgs e)
    {
        foreach (Control c in Controls)
        {
            c.Enabled = false;
        }
        if (bgw.IsBusy == false)
        {
            bgw.RunWorkerAsync();
        }
    }
    private void Update(int i)
    {
        if (InvokeRequired)
        {
            this.BeginInvoke(new Action<int>(Update), new Object[] { i });
            return;
        }
        using (var sp = new SerialPort(cbcomport.Text))
        {
            sp.Open();
            sp.WriteLine("AT" + Environment.NewLine);
            sp.WriteLine("AT+CMGF=1" + Environment.NewLine);
            sp.WriteLine("AT+CMGS=\"" + dt.Rows[i]["PhoneNo"] + "\"" + Environment.NewLine);
            sp.WriteLine(tbsms.Text + (char)26);
            if (sp.BytesToRead > 0)
            {
                tbsentto.Text = i + 1 + " of " + dt.Rows.Count;
            }
        }
    }        
    private void bgw_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            Update(i);
            Thread.Sleep(5000);
        }
    }
    private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        foreach (Control c in Controls)
        {
            c.Enabled = true;
        }
    }
于 2012-04-05T22:04:56.730 に答える