namespace TaskCancellation
{
public class PrimeTool
{
public static bool IsPrime(int candidate)
{
// Test whether the parameter is a prime number.
if ((candidate & 1) == 0)
{
if (candidate == 2)
{
return true;
}
else
{
return false;
}
}
for (int i = 3; (i * i) <= candidate; i += 2)
{
if ((candidate % i) == 0)
{
return false;
}
}
return candidate != 1;
}
}
}
//==============================================================
using System.Windows.Forms;
using System.Threading; //Added to use Cancellation
namespace TaskCancellation
{
public partial class Form1 : Form
{
Random rand = new Random();
//Declare a CancellationTokenSource giving it a class scope
//to be able to access it from 2 buttons
CancellationTokenSource cts = null;
//The CancellationTokenSource provides;
//a property Token to pass the Task constructor as well as to
//the method running in a task
//It also provides a method: Cancel() to allow you to request
//cancellation from another button.
//Cancellation is a cooperative process.
//Calling the Cancel method does not force cancellation, but
//just makes a request for cancellation.
//It is up to the method running in a task to add some code that
//acknowledges the cancellation request, then cancels itself
public Form1()
{
InitializeComponent();
}
//1. define a delegate with same signature as the crosss-threading handling
// method (the SetText method)
private delegate void RichTextBoxHandler(string s, RichTextBox rtb);
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
rtb.ScrollToCaret();
}
}
//This method must have the same signature as the Action<Object> delegate
//You are going to pass to it a CancellationToken object
//So your method has a way to cancel the task running it.
private void DisplayEvenRandomNumbers(Object obj)
{
//This method is passed a cancellation token, so you need
//to cast the obj
CancellationToken token = (CancellationToken)obj;
//Display 1,000 odd random
int counter = 0;
do
{
//check if cancellation has been requested
if (token.IsCancellationRequested)
{
//clean up resources
token.ThrowIfCancellationRequested();
//causes this method to exit, which ends or cancels the task.
}
int num = rand.Next();
if (num % 2 == 0)
{
// richTextBox2.AppendText(counter + " " + num + "\n");
SetText(counter + " " + num, richTextBox1);
//scroll down automaically
//rtb.ScrollToCaret();
counter++;
}
} while (counter < 1000);
}
private void btnStartTask_Click(object sender, EventArgs e)
{
//Use the constructor:
//Task(Action<Object>, Object, CancellationToken)
//your method must have the same signature as the
//Action<Object>delegate
Action<Object> action = DisplayEvenRandomNumbers;
//create a cancellation token to pass it to the method
//as well as to the Task constructor
//1. Create a CancellationTokenSource
cts = new CancellationTokenSource();
//Secondly, get the Token property
CancellationToken token = cts.Token;
//Create Task
Task task = new Task(action, token, token);
//one token is pass to the method, and another one is pass to the system constructor
task.Start();
}
private void btnCancelTask_Click(object sender, EventArgs e)
{
if (cts != null) //this if statement avoid no pointer exception
{
cts.Cancel(); //will request cancellation
}
}
private void startTaskOption2_Click(object sender, EventArgs e)
{
cts = new CancellationTokenSource();
//use task Constructor
//public Task(Action action,CancellationToken cancellationToken)
Task task = new Task(() => DisplayEvenRandomNumbers2(cts.Token), cts.Token);
task.Start();
}
//method for option 2
//Ref: https://msdn.microsoft.com/en-us/library/dd783029(v=vs.110).aspx
private void DisplayEvenRandomNumbers2(CancellationToken tk)
{
//This method is passed a cancellation token, so you need
//to cast the obj
//Display 1,000 odd random
int counter = 0;
do
{
//check if cancellation has been requested
if (tk.IsCancellationRequested)
{
//clean up resources
tk.ThrowIfCancellationRequested();
//causes this method to exit, which ends or cancels the task.
}
int num = rand.Next();
if (num % 2 == 0)
{
// richTextBox2.AppendText(counter + " " + num + "\n");
SetText(counter + " " + num, richTextBox1);
//scroll down automaically
//rtb.ScrollToCaret();
counter++;
}
} while (counter < 1000);
}
//===================================================================
private void btnDisplayPrimeNumbers_Click(object sender, EventArgs e)
{
cts = new CancellationTokenSource();
//use task Constructor
//public Task(Action action,CancellationToken cancellationToken)
Task task = new Task(() => DisplayPrimeNumbers(cts.Token), cts.Token);
task.Start();
}
//static void IsPrime()
private void DisplayPrimeNumbers(CancellationToken tk)
{
for (int i = 0; i <= 3000; i++)
{
if(tk.IsCancellationRequested)
{
//clean up resources
tk.ThrowIfCancellationRequested();
//causes this method to exit, which ends or cancels the task.
}
// PrimeTool created to run check from msdn
if (PrimeTool.IsPrime(i))
{
Console.ForegroundColor = ConsoleColor.Green;
SetText("Prime Numbers: " + i, richTextBox1);
}
}
}
private void btnCancelPrimeNumberTask_Click(object sender, EventArgs e)
{
if (cts != null) //this if statement avoid no pointer exception
{
cts.Cancel(); //will request cancellation
}
}
}
}
//Lab
//Add new button to start a task that displays prime numbers
//provide a button to cancel it.
//=================================================================

No comments:
Post a Comment