2013-05-04 3 views
0

Я хочу показать пример приложения семафоров для конкретной проблемы для моей домашней работы. Я добавил 3 кнопки в свою форму C#, и я хочу показать, что только одна кнопка в определенное время выполняет функцию банковского счета в моем коде. Когда я нажимаю три кнопки за две секунды, функция банковского счета должна запускаться только один раз. Поскольку у меня есть функция 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(); 
    } 
} 

}

ответ

0

я, возможно, неправильно ваш вопрос. Вы не хотите, чтобы кнопки ничего не делали, когда поток использовался? (Так что вы пропустите сделки?)

Попробуйте это:

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);

Вы инициализирует новый семафор никогда не выпускать его.

+0

Спасибо Джейсон, я сделал то, что вы сказали, но теперь функция банковского счета никогда не работает. Функция банковского счета должна запускаться один раз, даже если я нажимаю несколько раз в течение времени ожидания потока. – user2349578

+0

Изменение на 'new Semaphore (0, 1)' сделает так, что нить не сможет получить семафор. –

+0

Я попробовал «Semaphore semafor = new Semaphore (1,1)» с «if (semafor.WaitOne (0))», и все в порядке. Он работает, если семафор начинается с 1. – user2349578

0

Это действительно не похоже на правильное использование семафора. Определение вашей проблемы, если я правильно ее читаю, говорит, что три кнопки являются взаимоисключающими: нажатие любой из них будет отображать все кнопок, неактивных в течение шести секунд. У вас может использовать семафор для этого, но мьютекс будет более уместным.

В любом случае проблема, с которой вы столкнулись, заключается в том, что вы ожидаете семафора, поэтому при первой транзакции один из других потоков получит семафор и процесс. То, что вы хотите сделать, - попробуйте, чтобы приобрести семафор. Вот пример.

Примером последнего:

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) говорит: «Попробуйте приобрести семафор Если это не сразу доступны, а затем возвращать ложь Если она доступна, приобрести его и возвращает истину...»

Вы также можете сделать это в обработчике кнопок. То есть, обработчик кнопки получает семафор (используя WaitOne(0)), и пусть он выходит без запуска потока, если он не может получить семафор. Если он приобретает семафор, запустите поток и попросите поток proc освободить семафор, когда закончите.

Смежные вопросы