0

宿題の特定の問題に対するセマフォの適用例を示したいと思います。C# フォームに 3 つのボタンを追加しました。特定の時間に 1 つのボタンだけがコード内で銀行口座機能を実行することを示したいと思います。2 秒間に 3 つのボタンをクリックすると、銀行口座機能は 1 回だけ実行する必要があります。Thread.Sleep(6000) が銀行口座関数で 6 秒間待機しているためです。しかし、私のクリックの 3 つが 6 秒間隔で連続して実行されます。3 つのボタンを連続して押したときにコードを 1 回だけ実行するように変更するにはどうすればよいですか。コードは次のとおりです。

名前空間 semafor_form

{

public partial class Form1 : Form

   {
   Semaphore semafor=new Semaphore(1,1);

   delegate void SetTextCallback(string text);

   private void SetText(string text)
   {

       if (this.textBox2.InvokeRequired)
       {
           SetTextCallback d = new SetTextCallback(SetText);
           this.Invoke(d, new object[] { text });
       }
       else
       {
           this.textBox2.Text = text;
       }
   }

      public Form1()
    {
        InitializeComponent();

    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void BankAccount()
    {
       semafor.WaitOne();
       double a = Convert.ToDouble (textBox1.Text) + Convert.ToDouble (textBox2.Text);
       Thread.Sleep(6000);
       semafor.Release(); 
       SetText(a.ToString());  
    }

    private void btnATM_Click(object sender, EventArgs e)
    {
        Thread t = new Thread(new ThreadStart(BankAccount));
        t.Start();
     }

    private void btnCOUNTER_Click(object sender, EventArgs e)
    {

        Thread t = new Thread(new ThreadStart(BankAccount));
        t.Start();
    }

    private void btnINT_Click(object sender, EventArgs e)
    {

        Thread t = new Thread(new ThreadStart(BankAccount));
        t.Start();
    }
 }   

}

4

2 に答える 2

0

これは、セマフォの適切な使用法とは思えません。あなたの問題定義は、私が正しく読んでいれば、3 つのボタンは相互に排他的であると述べています。つまり、それらのいずれかを押すと、すべてのボタンが 6 秒間非アクティブになります。これにはセマフォを使用できますが、ミューテックスの方が適切です。

いずれにせよ、あなたが経験している問題は、セマフォを待っていることです。そのため、最初のトランザクションが完了すると、他のスレッドの 1 つがセマフォを取得して処理します。あなたがしたいことは、セマフォを取得しようとすることです。これが例です。

後者の例:

private void BankAccount()
{
   if (semafor.WaitOne(0))  // tries to acquire the semaphore
   {
       double a = Convert.ToDouble (textBox1.Text) + Convert.ToDouble (textBox2.Text);
       Thread.Sleep(6000);
       semafor.Release(); 
       SetText(a.ToString());
   }
}

WaitOne(0)、「セマフォを取得してみてください。すぐに取得できない場合は false を返します。取得できる場合は、取得して true を返します」と述べています。

ボタン ハンドラでこれを行うこともできます。つまり、ボタン ハンドラーに ( を使用してWaitOne(0)) セマフォを取得させ、セマフォを取得できない場合はスレッドを開始せずに終了させます。セマフォを取得する場合は、スレッドを開始し、完了時にスレッド proc にセマフォを解放させます。

于 2013-05-04T12:57:59.260 に答える