Handling and raising events

As we mentioned in the introduction of this chapter, events are any actions, such as a keypress, mouse movement, or I/O operation, performed by the user. Sometimes, events can be raised by system-generated operations such as creating/updating a record in a table. 

.NET Framework events are based on the delegate model, which follows the observer pattern. The observer pattern allows a subscriber to register for notifications and a publisher to register for push notifications. It's like late binding and is a way for an object to broadcast that something has happened.

A design pattern that allows you to subscribe/unsubscribe to a stream of events coming from a publisher is called an observer pattern.

For example, in the previous chapter, we worked on a code snippet where the program finds whether the character that was entered by the user is a vowel or not. Here, the user pressing a key on the keyboard is the publisher, which notifies the program regarding which key was pressed. Now, our program, which is a subscriber to the provider, responds to it by checking whether the character that was entered was a vowel or not and displays it on the screen.

A message that's sent by an object to notify it that an action has occurred is called an event. The object that raises this event is called an event sender or publisher. An object that receives and responds to an event is called a subscriber.

A publisher event can have multiple subscribers, while a subscriber can handle publishing events. Remember that multicast delegates, which we discussed in the previous sections, are extensively used in events (publish-subscribe pattern).

By default, if a publisher has multiple subscribers, all are invoked synchronously. C# supports calling these event methods asynchronously. We will understand this in more detail in the upcoming chapters.

Before we dive into an example, let's try to understand a few of the terms we are going to use:

event This is a keyword that's used to define an event in the publisher class in C#. 
EventHandler This method is used to handle an event. This may or may not have event data.
EventArgs It represents a base class for the class that contains event data.

 

Event handlers support two variations: one with no event data and another with event data. The following code represents a method that handles an event with no event data:

public delegate void EventHandler(object sender, EventArgs e);

The following code represents a method that handles an event with event data:

public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);

Let's look at an example and try to understand how we can raise events and handle them. 

In this scenario, we are going to have a banking application where customers make transactions such as creating new accounts, looking at their credit and debit amounts, and making requests for their total balance. We will raise events whenever such a transaction is made and notify the customer.

We will start with an Account class (publisher class), along with all the supporting methods, such as credit(), debit(), showbalance(), and initialdeposit(). These are the types of transactions a customer can operate their account with. Because the customer needs to be notified whenever such a transaction happens, we will define an event and an event handler with event data to handle the event:

public delegate void BankTransHandler(object sender, 
BankTransEventArgs e); // Delegate Definition
class Account
{
// Event Definition
public event BankTransHandler ProcessTransaction;
public int BALAmount;
public void SetInitialDeposit(int amount)
{
this.BALAmount = amount;
BankTransEventArgs e = new BankTransEventArgs(amount,
"InitialBalance");
// InitialBalance transaction made
OnProcessTransaction(e);
}
public void Debit(int debitAmount)
{
if (debitAmount < BALAmount)
{
BALAmount = BALAmount - debitAmount;
BankTransEventArgs e = new BankTransEventArgs(
debitAmount, "Debited");
OnProcessTransaction(e); // Debit transaction made
}
}
public void Credit(int creditAmount)
{
BALAmount = BALAmount + creditAmount;
BankTransEventArgs e = new BankTransEventArgs(
creditAmount, "Credited");
OnProcessTransaction(e); // Credit transaction made
}
public void ShowBalance()
{
BankTransEventArgs e = new BankTransEventArgs(
BALAmount, "Total Balance");
OnProcessTransaction(e); // Credit transaction made
}
protected virtual void OnProcessTransaction(
BankTransEventArgs e)
{
ProcessTransaction?.Invoke(this, e);
}
}

You may have observed the new class that we used in the previous example, that is, TrasactionEventArgs. This class carries event data. We are going to define this class now, which inherits from the EventArgs base class. We are going to define two variables, amt and type, to carry variables to the event handler:

public class BankTransEventArgs : EventArgs
{
private int _transactionAmount;
private string _transactionType;
public BankTransEventArgs(int amt, string type)
{
this._transactionAmount = amt;
this._transactionType = type;
}
public int TransactionAmount
{
get
{
return _transactionAmount;
}
}
public string TranactionType
{
get
{
return _transactionType;
}
}
}

Now, let's define a subscriber class to test how our event and event handler work. Here, we will define an AlertCustomer method whose signature matches the delegate that was declared in the publisher class. Pass a reference of this method to the delegate so that it reacts to the event:

public class EventSamples
{
private void AlertCustomer(object sender, BankTransEventArgs e)
{
Console.WriteLine("Your Account is {0} for Rs.{1} ",
e.TranactionType, e.TransactionAmount);
}
public void Run()
{
Account bankAccount = new Account();
bankAccount.ProcessTransaction += new
BankTransHandler(AlertCustomer);
bankAccount.SetInitialDeposit(5000);
bankAccount.ShowBalance();
bankAccount.Credit(500);
bankAccount.ShowBalance();
bankAccount.Debit(500);
bankAccount.ShowBalance();
}
}

When you execute the preceding program, for each transaction made, a transaction handler event is raised that invokes the notify-customer method and displays what type of transactions took place on the screen, as follows:

//Output:
Your Account is InitialBalance for Rs.5000
Your Account is Total Balance for Rs.5000
Your Account is Credited for Rs.500
Your Account is Total Balance for Rs.5500
Your Account is Debited for Rs.500
Your Account is Total Balance for Rs.5000
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.137.37