Reaper
Reaper

Reputation: 71

How do I make a method that will be executed once and only once?

In my program there is a screen with a "Print Receipt" button; on click of the button, I need to to call a method once and only once. Currently, the user can print multiple receipts and I do not know of a way to prevent this.

private async void PrintReceipt() 
{
    await _printReceiptInteractor.PrintTerminalReceiptAsync(_receipt).ConfigureAwait(false);
    Dispatcher.Dispatch(() => { this.Close(); });
}

How can I enforce the requirement of only executing this method once?

UPDATE: I manage to fix this by adding an IsBusy Property and and a method where i set IsBusy there , and just call that method , then i set IsBusy to false in the finally cause im using a try and catch statement.

Upvotes: 2

Views: 238

Answers (3)

Eldho
Eldho

Reputation: 8273

bool isbusy;
private async void PrintReceipt() 
{
    isbusy = true

    try
    {
      await _printReceiptInteractor.PrintTerminalReceiptAsync(_receipt)
    }
    finally
    {
       //This block will always exeute even if there is an exception
       isbusy = false
    }
}

The Print Command Here i have demoe

private ICommand _printCommand;
        public ICommand PrintCommand
        {
          get
          {
            return _printCommand ??(PrintCommand=
                   new RelayCommand(async () => await PrintReceipt(), CanExecute));
            }
        }


//Determine can execute command
private bool CanExecute()
{
      return !isbusy;
}

Xaml

<button Content="Print" Command={Binding PrintCommand"/>

The Button will disabled in state when the Command cannot be executed, that is during system is busy.

I would recommend you to read a MVVM

Upvotes: 0

Collin Stevens
Collin Stevens

Reputation: 817

You will either need to disable the GUI control that calls your method or you will need to create a property to such as a bool to track the entry to your method.

private bool _executed = false;
private void Method()
{
    if(!_executed)
    {
        _executed = true;
        // ...
    }
}

private readonly Button _button = new Button();
private void Method()
{
    _button.Enabled = false;
    // ...
}

private readonly object _lockObj = new object();
private void Method()
{
    // Prevent concurrent access
    lock(_lockObj)
    {
        if(!_executed)
        {
            _executed = true;
            // ...
        }
    }
}

Upvotes: 2

Hisham Maudarbocus
Hisham Maudarbocus

Reputation: 620

Try this:

private bool _printed = false;

private async void PrintReceipt()
{
    if(!_printed)
    {
        await _printReceiptInteractor.PrintTerminalReceiptAsync(_receipt).ConfigureAwait(false);
        Dispatcher.Dispatch(() => { this.Close(); });

        _printed = true;
    }
}

Upvotes: 0

Related Questions