In this post Asynchronous call using Delegates in C#,
we shall see on how to use delegates as reference to functions and make a Asynchronous
call to the references function.
Delegates in c# act as function pointers to functions, they can refer to any function which has the same signature as the delegate. To know more about the basics of Delegates refer to the post Delegates in C#.
Delegates in c# act as function pointers to functions, they can refer to any function which has the same signature as the delegate. To know more about the basics of Delegates refer to the post Delegates in C#.
Here we shall see on how Delegates can be used to make Asynchronous
calls to the references function, when we make a Asynchronous call the calling
thread does not wait for the referenced function to complete its execution, it
just makes the call and forgets it, the referenced function completes its
execution and notifies the caller by calling the Callback function.
Let us try to use Delegates to populate a DataGridView
with data, the Delegate will be mapped to a function in the Domain class and a Asynchronous
call is made to the mapped function to populate the DataGridView.
First let us create a Domain layer class clsEmployee,
and add a method GetEmployeeList
to this class, our delegate will be mapped to
this method to get the details.
class clsEmployee
{
public DataTable GetEmployeeList(int
DepartmentID)
{
// Read the
connection string from the app.config file.
string
strConn = ConfigurationSettings.AppSettings["ConnectionString"].ToString();
SqlConnection
objConn = new SqlConnection(strConn);
SqlCommand
objCmd = new SqlCommand("SELECT * FROM EMPLOYEE WHERE DepartmentID = "
+ DepartmentID, objConn);
SqlDataAdapter
objDA = new SqlDataAdapter(objCmd);
DataSet
dsEmployee = new DataSet();
//
objDA.Fill(dsEmployee, "dtEmployee");
//
System.Threading.Thread.Sleep(5000);
return
dsEmployee.Tables["dtEmployee"];
}
}
Fine, now we
will move to the From End code, declare the delegate and map it to the above
method.
Declare the Delegate
delegate DataTable GetEmployeeListDelegate(int intDepartmentID);
delegate DataTable GetEmployeeListDelegate(int intDepartmentID);
Initialize the delegate and map it to the function in
the Domain class.
clsEmployee objEmployee = new
clsEmployee();
delegate_GetEmployees = new GetEmployeeListDelegate(objEmployee.GetEmployeeList);
delegate_GetEmployees.BeginInvoke(Convert.ToInt16(cmbDepartment.SelectedValue),
LoadEmployeeCallBack, null);
Here the Delegate in initialized and mapped to the
function in the line
delegate_GetEmployees = new GetEmployeeListDelegate(objEmployee.GetEmployeeList);
The call to the mapped function is made indirectly by invoking the delegate, and a reference to the Callback function is passed in the line
delegate_GetEmployees.BeginInvoke(Convert.ToInt16(cmbDepartment.SelectedValue), LoadEmployeeCallBack, null);
delegate_GetEmployees = new GetEmployeeListDelegate(objEmployee.GetEmployeeList);
The call to the mapped function is made indirectly by invoking the delegate, and a reference to the Callback function is passed in the line
delegate_GetEmployees.BeginInvoke(Convert.ToInt16(cmbDepartment.SelectedValue), LoadEmployeeCallBack, null);
When this like gets executed, the mapped function is
called through the delegate and a reference to the call back function is
passed.
Remember we are making an Asynchronous call with the
delegate hence, the User Interface will be not get locked, Once the call is
made the UI is free for the user to perform other activities, the mapped
function will complete the execution and call the callback function to populate
the GridView
private void
LoadEmployeeCallBack(IAsyncResult ar)
{
DataTable
dtEmployees;
dtEmployees =
delegate_GetEmployees.EndInvoke(ar);
//
loadGridView(dtEmployees);
}
Here if you notice we are not binding the result
DataTable to the GridView in the callback function, this cannot be done since
this function is executing in a different thread, trying to bind the datatable dtEmployees to the GridView gvEmployees here will
throw the following exception.
Cross-thread operation not valid: Control
'gvEmployees' accessed from a thread other than the thread it was created on.
Hence we need to help of another delegate to populate the Grid with the data.
Hence we need to help of another delegate to populate the Grid with the data.
delegate void loadGridViewDelegate(DataTable
dtEmployee);
private void loadGridView(DataTable dtEmployees)
private void loadGridView(DataTable dtEmployees)
{
if
(gvEmployees.InvokeRequired)
{
loadGridViewDelegate
del = new loadGridViewDelegate(loadGridView);
gvEmployees.Invoke(del, new object[] {
dtEmployees });
}
else
{
gvEmployees.DataSource = dtEmployees;
}
}
The Complete code is as follows
Domain Class
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
namespace WinApp
{
class clsEmployee
{
public DataTable GetEmployeeList(int
DepartmentID)
{
// Read
the connection string from the app.config file.
string
strConn = ConfigurationSettings.AppSettings["ConnectionString"].ToString();
SqlConnection
objConn = new SqlConnection(strConn);
SqlCommand
objCmd = new SqlCommand("SELECT * FROM EMPLOYEE WHERE DepartmentID = "
+ DepartmentID, objConn);
SqlDataAdapter
objDA = new SqlDataAdapter(objCmd);
DataSet
dsEmployee = new DataSet();
//
objDA.Fill(dsEmployee, "dtEmployee");
//
System.Threading.Thread.Sleep(5000);
return
dsEmployee.Tables["dtEmployee"];
}
}
}
UI Windows Form
code
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.Data.SqlClient;
namespace WinApp
{
delegate DataTable GetEmployeeListDelegate(int intDepartmentID);
delegate void loadGridViewDelegate(DataTable dtEmployee);
//
public partial class frmViewEmployees : Form
{
GetEmployeeListDelegate
delegate_GetEmployees;
//
private
void btnLoadEmployees_Click(object sender, EventArgs
e)
{
clsEmployee
objEmployee = new clsEmployee();
delegate_GetEmployees = new GetEmployeeListDelegate(objEmployee.GetEmployeeList);
delegate_GetEmployees.BeginInvoke(Convert.ToInt16(cmbDepartment.SelectedValue),
LoadEmployeeCallBack, null);
}
//
private
void LoadEmployeeCallBack(IAsyncResult ar)
{
DataTable
dtEmployees;
dtEmployees =
delegate_GetEmployees.EndInvoke(ar);
//
gvEmployees.DataSource =
dtEmployees;
loadGridView(dtEmployees);
}
//
private
void loadGridView(DataTable
dtEmployees)
{
if
(gvEmployees.InvokeRequired)
{
loadGridViewDelegate
del = new loadGridViewDelegate(loadGridView);
gvEmployees.Invoke(del, new object[] {
dtEmployees });
}
else
{
gvEmployees.DataSource =
dtEmployees;
}
}
//
public
frmViewEmployees()
{
InitializeComponent();
}
//
private
void frmViewEmployees_Load(object sender, EventArgs
e)
{
BindDepartments();
}
//
private
void BindDepartments()
{
// Read
the connection string from the app.config file.
string
strConn = ConfigurationSettings.AppSettings["ConnectionString"].ToString();
SqlConnection
objConn = new SqlConnection(strConn);
SqlCommand
objCmd = new SqlCommand("SELECT 0 as ID,'-Select-' as Name UNION SELECT ID,
NAME FROM DEPARTMENT", objConn);
SqlDataAdapter
objDA = new SqlDataAdapter(objCmd);
DataSet
dsDepartment = new DataSet();
//
objDA.Fill(dsDepartment, "dtDepartment");
//
cmbDepartment.DataSource =
dsDepartment.Tables["dtDepartment"];
cmbDepartment.DisplayMember = "Name";
cmbDepartment.ValueMember = "ID";
}
}
}
That’s it we seen on how to make an Asynchronous
call using Delegates in C#.
Related Posts
Delegates in C#
Multicast Delegates
Event handling using Delegates in C#
Synchronous call using Delegates in C#
Asynchronous callback using Delegates in C#
Related Posts
Delegates in C#
Multicast Delegates
Event handling using Delegates in C#
Synchronous call using Delegates in C#
Asynchronous callback using Delegates in C#
3 comments:
Excellent
Wonderful bloggers like yourself who would positively reply encouraged me to be more open and engaging in commenting.So know it's helpful.
Selenium training in Chennai
Selenium training in Bangalore
Selenium training in Pune
Selenium Online training
Intresting article...thank you for sharing. Java training in Chennai | Certification | Online Course Training | Java training in Bangalore | Certification | Online Course Training | Java training in Hyderabad | Certification | Online Course Training | Java training in Coimbatore | Certification | Online Course Training | Java training in Online | Certification | Online Course Training
Post a Comment