表单应用程序的简单信号量实现

本文关键字:信号量 实现 简单 应用程序 表单 | 更新日期: 2023-09-27 18:12:01

我想为我的作业展示一个特定问题的信号量示例应用程序。我在c#表单中添加了3个按钮,我想显示在特定时间只有一个按钮执行代码中的银行帐户函数。当我在两秒钟内点击三个按钮时,银行账户功能必须只运行一次。因为我在银行账户功能中有一个Thread.Sleep(6000),等待6秒。但是我的三次点击间隔是连续的6秒。我怎么能改变我的代码,只运行一次,当我按三个按钮连续。代码是:

名称空间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();
    }
 }   

}

表单应用程序的简单信号量实现

我可能误解了你的问题。当线程被使用时,您不希望按钮做任何事情?(所以你会错过交易?)

试试这个:

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

尝试将Semaphore semafor=new Semaphore(1,1);更改为Semaphore semafor=new Semaphore(0,1);

你正在初始化一个新的信号量,而没有释放它。

这听起来确实不像是信号量的适当使用。如果我没看错的话,你的问题定义是,这三个按钮是互斥的:按下其中任何一个都会使所有按钮在6秒内处于非活动状态。可以使用信号量,但是互斥锁更合适。

无论如何,您遇到的问题是您正在等待信号量,因此当第一个事务完成时,其他线程中的一个将获得信号量和进程。您要做的是尝试获取信号量。下面是一个例子。

后者的一个例子:

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)),如果无法获取信号量,则让它退出而不启动线程。如果它确实获得了信号量,则启动线程,并让线程进程在完成后释放信号量。