using System.Windows.Forms;
namespace IntroToAsynchronouseMethods
{
public partial class Form1 : Form
{
Random rand = new Random();
public Form1()
{
InitializeComponent();
}
private void btnRunSync_Click(object sender, EventArgs e)
{
//Calling both methods synchronously
//both methods run in the main thread (UIthread).
//the main thread can only run one after another
DisplayOddRandomNumbers();
DisplayEvenRandomNumbers();
}
private void btnRunAsynchronous_Click(object sender, EventArgs e)
{
//Step 1: Create a type of delegate
//Need a delegate type with same signature as DisplayOddRandomMethod
//Since .Net defines an Action delegate
//public delegate void Action() that has the same signature as the method
//you can use it.
//Step 2.
//Once a delegate type is defined or determined
//create a delegate object and reference it to the method you want to run asynchronously
Action oddAction = DisplayOddRandomNumbers;
//now apply the BeginInvoke method of the delegate
oddAction.BeginInvoke(null, null);
//run the second display asynchronously
Action evenAction = DisplayEvenRandomNumbers;
evenAction.BeginInvoke(null, null);
//Run the 3rd display method asynchronously
//you need to pass an integer value to it thru the BeginInvoke
Action<int> divBy3Action = DisplayDivisibleBy3;
//we want 1500 values that are divisible by 3
divBy3Action.BeginInvoke(1500, null, null);
}
//define 2 methods
private void DisplayOddRandomNumbers()
{
//Display 1,000 odd random
int counter = 0;
do
{
int num = rand.Next();
if (num % 2 != 0)
{
//richTextBox1.AppendText(counter + " " + num + "\n");
SetText(counter + " " + num, richTextBox1);
//scroll down automaically
//rtb.ScrollToCaret();
counter++;
}
} while (counter < 1000);
}
private void DisplayEvenRandomNumbers()
{
//Display 1,000 odd random
int counter = 0;
do
{
int num = rand.Next();
if (num % 2 == 0)
{
// richTextBox2.AppendText(counter + " " + num + "\n");
SetText(counter + " " + num, richTextBox2);
//scroll down automaically
//rtb.ScrollToCaret();
counter++;
}
} while (counter < 1000);
}
//Define a 3rd method to run asynchronously
//but this time this method takes one or more parameters
private void DisplayDivisibleBy3(int maxCount)
{
//Display 1,000 odd random
int counter = 0;
do
{
int num = rand.Next();
if (num % 3 == 0)
{
// richTextBox2.AppendText(counter + " " + num + "\n");
SetText(counter + " " + num, richTextBox3);
//scroll down automaically
//rtb.ScrollToCaret();
counter++;
}
} while (counter < maxCount);
}
//Define a delegate with same signature as the cross-threading
//handling method (the SetText method)
private delegate void RichTextBoxHandler(string s, RichTextBox rtb);
//method to allow other threads to access the UI RichTextBox
//this method should accept the string that you want to display in the UI
private void SetText(string s, RichTextBox rtb)
{
if (rtb.InvokeRequired)
{
//create a delegate object
RichTextBoxHandler handler = SetText;
Invoke(handler, s, rtb);
}
else
{
rtb.AppendText(s + "\n");
//scroll down automaically
rtb.ScrollToCaret();
}
}
//=======Asynchronous method that return a value===============
private void btnAsyncMethodReturnValue_Click(object sender, EventArgs e)
{
//To get a return value from an asynchronous method
//you need to define a callback method. This callback method gets called when
//the thread or that asynchronous method terminates.
//The return value can be retrieved from the callback method.
//The callback method must have the same signature as AsyncCallback delegate
//Create a delegate object for asynchronous method
//use the Func<> delegate because the method returns value.
Func<double> function = GetAvgOfOddRandomValues;
//Create an AsyncCallack delegate to reference the method that gets called
AsyncCallback callback = CallbackOfGetAvgOfRadomValues;
//When the asynchronous completes. The callbcak method has the return value
function.BeginInvoke(callback, function);
}
//define a callback method for the asynchronous GetAvgOfRandomValues
private void CallbackOfGetAvgOfRadomValues(IAsyncResult ar)
{
//you need to retrive the return value
//you need to use the SAME delegate object used to call the BeginInvoke.
//get the function object passed as the last parameter in the BeginInvoke
Func<double> function = (Func<double>)ar.AsyncState;
//Get the return value from the asynchronous method
double avg = function.EndInvoke(ar);
SetText("average = " + avg, richTextBox4);
}
//method to run asynchronously. This method returns a value
private double GetAvgOfOddRandomValues()
{
int counter = 0;
double sum = 0;
do
{
int num = rand.Next();
if (num % 2 != 0)
{
sum += num;
counter++;
}
} while (counter < 5000000);
return sum/ counter;
}
}
}
//To read more links:
//https://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.110).aspx
//https://msdn.microsoft.com/en-us/library/system.action(v=vs.110).aspx
//http://www.c-sharpcorner.com/UploadFile/835123/cross-thread-operations-in-C-Sharp/
//https://msdn.microsoft.com/en-us/library/hh191443.aspx
//http://www.csharp-examples.net/create-asynchronous-method/
//Lab Assignment: Due Wednesday 2-4; //New Project
//Define a method that takes no parameters and returns a double
//The method is to run asynchronously and computes the sum of Log of all the
//random values [ sum += Math.log(num)] generated. (generate few millions)
//Get and display the result thru its callback method
//====================================================
//Define a method that takes 2 integer values
//Add all the values between the 2 parameters incrementing by 0.01
//run the method asynchronously
//the method is to return the average value
//get and display its return value from the callback

No comments:
Post a Comment