RequestCycle goes null when using a separate thread - multithreading

I am using a separate thread to handle the processing of a file. The main thread holds the table to display to the user using a listView, and uses an AjaxSelfUpdatingTimer to refresh the list every second.
The problem is, after processing about 100 lines in my CSV file, I keep getting a no requestCyle exception:
Exception in thread "Thread-12" org.apache.wicket.WicketRuntimeException: No RequestCycle is currently set!
at org.apache.wicket.Component.getRequest(Component.java:1804)
at org.apache.wicket.markup.html.WebPage.dirty(WebPage.java:318)
at org.apache.wicket.Page.dirty(Page.java:249)
at org.apache.wicket.Page.componentStateChanging(Page.java:926)
at org.apache.wicket.Component.addStateChange(Component.java:3528)
at org.apache.wicket.Component.error(Component.java:1225)
at com.wicket.BulkLoadPage$BatchLoaderProcessingThread.processLine(BulkLoadPage.java:806)
at com.wicket.BulkLoadPage$BatchLoaderProcessingThread.run(BulkLoadPage.java:674)
at java.lang.Thread.run(Thread.java:662)
these are my runnable classes the thread calls:
class BatchLoaderProcessingThread implements Runnable
{
#Override
public void run()
{
processLine();
loaderFinished();
}
public void cancelThread()
{
cancelLoaderThread = true;
}
}
class BatchDeleteProcessingThread implements Runnable
{
#Override
public void run()
{
processLine();
deleterFinished();
}
public void cancelThread()
{
cancelDeleterThread = true;
}
}
I don't understand why the requestCycle would just go null.. How can I prevent this from happening?
Edit:
Commenting out feedback message do troubleshoot requestRecycle error, I receive this error:
java.io.IOException: Read error
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:220)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.read1(BufferedReader.java:185)
at java.io.BufferedReader.read(BufferedReader.java:261)
at java.io.BufferedReader.fill(BufferedReader.java:136)
Dec 30 13:14:31 ERROR BulkLoadPage-java.io.IOException: Read error
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at au.com.bytecode.opencsv.CSVReader.getNextLine(CSVReader.java:266)
at au.com.bytecode.opencsv.CSVReader.readNext(CSVReader.java:233)
at com..wicket.BulkLoadPage.processLine(BulkLoadPage.java:547)
at com..wicket.BulkLoadPage.access$0(BulkLoadPage.java:532)
at
com..wicket.BulkLoadPage$BatchLoaderProcessingThread.run(BulkLoadPage.java:1294)
at java.lang.Thread.run(Thread.java:662)
this error only occurs with the larger file as well. All of the lines inside the csv are duplicate only to mimic a large file.. so all lines are the same, and there shouldn't be an error caused directly from the file. Is there something else that I should be looking for that would cause this error from using another thread?

RequestCycle is a thread local singleton. If you're running a process in another thread that really means the RequestCycle singleton doesn't exist in your new thread.
The following example is placed on https://repo.twinstone.org/projects/WISTF/repos/wicket-examples-1.4/browse
The idea is about holding the reference to the current RequestCycle, you cannot call RequestCycle.get() due to the thread local singleton doesn't exist in any other thread. This CustomRequestCycle implementation is ever waiting until the new thread notify its finishing. The counter of loops is just a protection to do not freeze the primary thread if the WaitingRunnable stops working/freezes.
RESULTS oF TESTS:
Check your logs for case 1, the separate thread is finishing very soon, RequestCycle doesn't wait for detaching
http://localhost:8080/wicket-examples14/wait?millis=10
DEBUG - CustomRequestCycle - Waiting until notify: 0
INFO - WaitingRunnableNotifier - Separate thread waiting finished cz.wicketstuff.enteam.wicket.examples14.request.ThreadWaitingPage
INFO - CustomRequestCycle - Notifier returned: Successfully finished
Check your logs for case 2, the separate thread is finishing in time, RequestCycle has to wait for detaching
http://localhost:8080/wicket-examples14/wait?millis=3000
DEBUG - CustomRequestCycle - Waiting until notify: 0
DEBUG - CustomRequestCycle - Waiting until notify: 1
DEBUG - CustomRequestCycle - Waiting until notify: 2
INFO - WaitingRunnableNotifier - Separate thread waiting finished cz.wicketstuff.enteam.wicket.examples14.request.ThreadWaitingPage
INFO - CustomRequestCycle - Notifier returned: Successfully finished
Check your logs for case 3, the separate thread is finishing on time, RequestCycle is already detached
http://localhost:8080/wicket-examples14/wait?millis=10000
DEBUG - CustomRequestCycle - Waiting until notify: 0
DEBUG - CustomRequestCycle - Waiting until notify: 1
DEBUG - CustomRequestCycle - Waiting until notify: 2
DEBUG - CustomRequestCycle - Waiting until notify: 3
DEBUG - CustomRequestCycle - Waiting until notify: 4
DEBUG - CustomRequestCycle - Waiting until notify: 5
DEBUG - CustomRequestCycle - Waiting until notify: 6
DEBUG - CustomRequestCycle - Waiting until notify: 7
INFO - CustomRequestCycle - Notifier returned: null
INFO - WaitingRunnableNotifier - Separate thread waiting finished cz.wicketstuff.enteam.wicket.examples14.request.ThreadWaitingPage
SOURCES:
WicketApplication
#Override
public RequestCycle newRequestCycle(Request request, Response response) {
return new CustomRequestCycle(this, (WebRequest)request, (WebResponse)response);
}
CustomRequestCycle
public class CustomRequestCycle extends WebRequestCycle implements INotifier<String> {
private static final Logger log = LoggerFactory.getLogger(CustomRequestCycle.class);
private long sleepTime = 1000L;
private long maxLoops = 8;
private boolean canDetach = true;
private String notifierResult;
public CustomRequestCycle(WicketApplication application, WebRequest request,
Response response) {
super(application, request, response);
}
public void notifyAny(String payload) {
notifierResult = payload;
canDetach = true;
}
#Override
public void detach() {
long counter = 0;
while(!canDetach && maxLoops > counter) {
log.debug("Waiting until notify: " + counter);
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// do nothing
}
counter++;
}
log.info("Notifier returned: " + notifierResult);
super.detach();
}
public static CustomRequestCycle get() {
return (CustomRequestCycle)RequestCycle.get();
}
/**
* #return the canDetach
*/
public boolean isCanDetach() {
return canDetach;
}
/**
* #param canDetach the canDetach to set
*/
public void setCanDetach(boolean canDetach) {
this.canDetach = canDetach;
}
}
WaitingRunnableNotifier
public class WaitingRunnableNotifier implements Runnable {
private static final Logger log = LoggerFactory.getLogger(WaitingRunnableNotifier.class);
private final long waitTime;
private RequestCycle requestCycle;
private INotifier<String> notifier;
public WaitingRunnableNotifier(RequestCycle requestCycle, long waitTime, INotifier<String> notifier) {
super();
this.notifier = notifier;
this.requestCycle = requestCycle;
this.waitTime = waitTime;
}
public void run() {
String message = null;
try {
try {
Thread.sleep(waitTime);
} catch (InterruptedException e) {
}
log.info("Separate thread waiting finished " + requestCycle.getResponsePageClass().getCanonicalName());
message = "Successfully finished";
} catch (Exception e) {
log.error("Exception during WaitingRunnableNotifier.run()", e);
message = "Exception: " + e.getMessage();
} finally {
notifier.notifyAny(message);
clean();
}
}
/**
* Clean object references
*/
private void clean() {
requestCycle = null;
notifier = null;
}
}
ThreadWaitingPage is a page with parameter 'millis'. There you can invoke the another thread and wait unitl it is finished.
public class ThreadWaitingPage extends WebPage {
private static final long serialVersionUID = 1L;
private final long millis;
public ThreadWaitingPage(final PageParameters parameters) {
super(parameters);
millis = parameters.getLong("millis");
add(new Label("millis", String.valueOf(millis)));
}
#Override
protected void onInitialize() {
super.onInitialize();
CustomRequestCycle requestCycle = CustomRequestCycle.get();
requestCycle.setCanDetach(false);
new Thread(new WaitingRunnableNotifier(requestCycle, millis, requestCycle)).start();
}
}

Ideally, you shouldn't be creating your own threads, the container should be left to do all that for you. Of course, this means you can't leave bulk processes running in the background between requests.
I've done something similar before (breaking the rule I just mentioned!) and the easiest way is to keep Wicket out of your own threads. If your threads populate a List for example, and your ajax timer callback extracts the records from the list and adds them to the list view.
The problem with list views though is you have to add the parent component to the ajax request target, meaning that the whole list view will be sent back in the ajax response, not just the new entries you've added but all the old ones as well, which would defeat the point of loading them incrementally.
As its only a CSV file, it might be better for you to use a data table, and write a data provider to open the file and read only the records for that request which should be much simpler.

I have temporarily fixed this issue by first loading the lines into a string ArrayList in the main thread and just read from that list inside the thread..
I don't really see any latency issues, so maybe this can be considered a good alternative? If it isn't please let me know, otherwise hopefully this helps someone else some day who struggles with this.
I have also posted my issue here:
http://apache-wicket.1842946.n4.nabble.com/MultiThreading-issues-with-Wicket-td4663325.html#a4663389
and was given some good resource links to review:
Multithreading in wicket:
http://javathoughts.capesugarbird.com/2008/04/spawning-thread-for-lengthy-operation.html
RequestCycle:
http://wicket.apache.org/guide/guide/chapter8.html

Related

Execution of a thread after it got interrupted

A thread is executing task to print numbers from 0 to n, and sleeps for 4000 ms after every print statement. Somewhere in the middle thread gets interrupted. Now when the same thread starts its execution, where will it start from , will it start printing the numbers from 0 to n again, or it will print numbers from where it got interrupted.
In both cases what are the reasons and how it is being handled?
public class Main {
public static void main(String[] args) throws InterruptedException {
SleepTest sleepTest = new SleepTest();
Thread thread = new Thread(sleepTest);
thread.start();
thread.interrupt();
}
}
public class SleepTest implements Runnable{
static int sleep = 10;
public void run(){
for (int i =0; i<10; i++){
System.out.println(i);
try {
Thread.currentThread().interrupt();
Thread.sleep(4000);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
System.out.println(Thread.interrupted());
}
}
Calling a interrupt() on a thread object can only suggest thread to stop. It is not guarantee that the thread will stop.
It completely depends on the implementation of run() method of thread.
In your case in run() you are catching the InterruptedException and you are printing the exception trace but not stopping the thread. Thats why thread will never stop on InterruptedException and continue the execution.
It may look like thread is getting stopped(by seeing exception trace) when see the output on console.
Refer interrupt interrupted isinterrupted in Java
All Thread.currentThread().interrupt() does is update the value of field interrupted to true.
Let's see the program's flow and how the interrupted field is assigned values:
public class Main {
public static void main(String[] args) throws InterruptedException {
SleepTest sleepTest = new SleepTest();
Thread thread = new Thread(sleepTest, "Sub Thread"); // Give a name to this thread
thread.start(); // main thread spawns the "Sub Thread". Value of "interrupted" - false
thread.interrupt(); // called by main thread. Value of "interrupted" - true
}
}
public class SleepTest implements Runnable{
static int sleep = 10;
public void run(){
System.out.println(Thread.currentThread().getName()+" "+Thread.interrupted()); // prints "Sub Thread true"
for (int i =0; i<10; i++){
System.out.println(i);
try {
Thread.currentThread().interrupt(); // no matter what value is for interrupted, it is assigned the value "true"
Thread.sleep(4000); // Can't call sleep with a "true" interrupted status. Exception is thrown. Note that, when the exception is thrown, the value of interrupted is "reset", i.e., set to false
} catch (InterruptedException exception) {
exception.printStackTrace(); // whatever
}
System.out.println(Thread.interrupted()); // returns the value of interrupted and resets it to false
}
}
To answer
where will it start from , will it start printing the numbers from 0
to n again, or it will print numbers from where it got interrupted.
Calling interrupt will not cause make it start over because all it is doing at this call is set value interrupted to false (and not modifying anything else).

Java EventListener inside of SwingWorker

OK, so I'm a bit new to SwingWorker in Java.
I've built a Java GUI that, when the "Start" button is pressed, launches several SwingWorker threads. The first thread simply keeps track of run time and updates the GUI appropriately. The second one plays a series of sounds files. The third (and problematic) thread should monitor the serial port for incoming data to be manipulated later on down the road. All of these threads will be running for a while, hence them being SwingWorkers.
I am using the jSSC library (https://code.google.com/p/java-simple-serial-connector/wiki/jSSC_examples) to read data from the serial port, and it does so by firing an eventListener.
My question: Is it redundant/inelegant to code an EventListener inside of a SwingWorker thread? And if so, is there a better way to go about this?
Here is a bit of my code:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
SerialPort serialPort = findPort(); // returns a serialport I can use to read data from.
SwingWorker worker1 = new SwingWorker<Void, Void>(){
#Override
protected Void doInBackground() throws Exception {
long elapsedTime, startTime = System.currentTimeMillis();
while (true){
Thread.sleep(1000);
elapsedTime = (System.currentTimeMillis() - startTime)/1000;
jTimeField.setText(String.format("%02d:%02d:%02d", elapsedTime/3600, (elapsedTime%3600)/60, elapsedTime%60));
if (isCancelled()){} /* Check if thread has been canceled */
}
}
};
SwingWorker worker2 = new SwingWorker<Void, Void>(){
#Override
protected Void doInBackground() throws Exception {
// This Thread: Plays music files; Self terminates; On termination also terminates worker 1 and 3 via cancel().
}
};
SwingWorker worker3 = new SwingWorker<Void, Void>(){
#Override
protected Void doInBackground() throws Exception {
serialPort.addEventListener(new SerialPortReader());
return null;
}
class SerialPortReader implements SerialPortEventListener {
#Override
public void serialEvent(SerialPortEvent event) {
byte buffer[];
if (event.isRXCHAR() && event.getEventValue() > 0){
buffer = serialPort.readBytes();
for (byte b: buffer){
// Do stuff with incoming data
}
}
}
}
};
}
Any and all constructive criticism is appreciated.
It does not do any good to add the event listener in your swingworker thread and then return once that's done. Why not just add the listener from your EDT and, if it takes long to process events, fire off processing threads from there? Listening to events can't be blocking, that would defeat the entire Observer pattern.

How to get an exception raised from a long running background Task without having main thread to wait

I want to perform some long running operation (e.g. listening to some event raised by OS) on the background thread. Most of the times, operation will run continuously without any problem. But in certain rare conditions, OS level API sends some error code and I need to raise exception from background thread which has to be propagated to the main thread to show it to the user of my WinFrom application.
I had decided to use BackgroundWorker for this. But .NET 4.0 provides Task class of the Task Parallel Library which is a better option as per various blogs on the TPL.
In my application, I have to kick off the background task before actual form is shown. Since actual code is quite complex, I have written some sample code simulating real time problem:
public static Task task;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
ThreadTest tt = new ThreadTest();
task = new Task(() => tt.PerformTask("hi"));
task.Start();
try
{
task.Wait();
}
catch (AggregateException aggregateException)
{
// Handle exception here.
}
Application.Run(new Form1());
}
In this code, I never see the main form simply because background task keeps running without exception and task.Wait() call makes the current thread waiting until background task finishes!
Can I use TPL's Task for such scenarios where main thread should not wait until background task is finished but at the same time, it should get exception details whenever exception is raised from the background task?
In above code, one of the solutions could be to move the task creation code at some later stage. But my question is more academic in this case.
Yes you can. Please see the code below.
The program code is:
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
Task longRunningTask = new Task((state) =>
{
LongRunningWork.DoWork( cancellationTokenSource.Token);
},cancellationTokenSource.Token,TaskCreationOptions.LongRunning);
var newForm = new Form1(cancellationTokenSource);
new Thread((state) =>
{
longRunningTask.Start();
try
{
longRunningTask.Wait();
}
catch (AggregateException exception)
{
Action<Exception> showError = (ex) => MessageBox.Show(state as Form, ex.Message);
var mainForm = state as Form;
if (mainForm != null)
{
mainForm.BeginInvoke(showError, exception.InnerException);
}
}
}).Start(newForm);
Application.Run(newForm);
And the code for the long running task is:
public class LongRunningWork
{
public static void DoWork( CancellationToken cancellationToken)
{
int iterationCount = 0;
//While the
while (!cancellationToken.IsCancellationRequested &&iterationCount <5)
{
//Mimic that we do some long jobs here
Thread.Sleep(1000);
iterationCount++;
//The jobs may throw the exception on the specific condition
if (iterationCount ==5)
{
throw new InvalidOperationException("Invalid action");
}
}
//cancel the task
cancellationToken.ThrowIfCancellationRequested();
}
}
Finally, the code for the Form1 which includes a exit button, whose function is to terminate the program on clicking.
public partial class Form1 : Form
{
private CancellationTokenSource _cancellationTokenSource;
public Form1()
{
InitializeComponent();
}
public Form1(CancellationTokenSource cancellationTokenSource):this()
{
_cancellationTokenSource = cancellationTokenSource;
}
private void exitBtn_Click(object sender, EventArgs e)
{
//Cancel out the task
if (_cancellationTokenSource != null)
{
_cancellationTokenSource.Cancel();
}
//Exit the program
Application.Exit();
}
}
Start your long running operation from the form itself rather than before the form is created. Remember that Application.Run() starts a message loop on the current thread, but that means you can use that message loop to poll your task from the Timer class.
class Form1 : Form
{
private Timer PollingTimer;
private Task BackgroundTask;
public Form1()
{
InitializeComponent();
// Begin the background task.
ThreadTest tt = new ThreadTest();
this.BackgroundTask = new Task(() => tt.PerformTask("hi"));
this.BackgroundTask.Start();
// Monitor the task's status by polling it regularly.
this.PollingTimer = new Timer();
this.PollingTimer.Interval = 1000; // In milliseconds.
this.PollingTimer.Tick += timerCallback;
this.PollingTimer.Start();
}
private timerCallback(object sender, EventArgs e)
{
if (this.BackgroundTask.IsFaulted)
{
// Exception information is in BackgroundTask.Exception.
}
}
}
If you dislike polling (which I do), you'll need to catch the exception from your task and marshall it back to your UI thread. The best way to do that is simply not catch the exception in the task itself and provide a continuation method which will only execute on error.
class Form1 : Form
{
private Task BackgroundTask;
public Form1()
{
InitializeComponent();
// Capture the UI thread context.
// (Note, it may be safer to run this in the Form.Load event than the constructor.
var uiContext = TaskScheduler.FromCurrentSynchronizationContext();
// Begin the background task.
ThreadTest tt = new ThreadTest();
this.BackgroundTask = new Task(() => tt.PerformTask("hi"))
// Schedule a continuation to be executed after the task is completed.
.ContinueWith((t,arg) =>
{
// Exception information is in t.Exception
},null, null,
// Only execute the continuation if the task throws an exception.
TaskContinuationOptions.OnlyOnFaulted,
// Execute the continuation on the UI thread we captured above.
uiContext);
this.BackgroundTask.Start();
}
}
MSDN references for Task.ContinueWith() and TaskScheduler.FromCurrentSynchronizationContext().
And, if you have the luxury of .NET 4.5 with async and await:
class Form1 : Form
{
private Task BackgroundTask;
public Form1()
{
InitializeComponent();
}
private async void Form1_Load(object sender, EventArgs e)
{
ThreadTest tt = new ThreadTest();
try
{
// Move your Task creation and start logic into a method.
await tt.RunAsync();
}
catch (Exception ex)
{
// Really smart compiler writers make sure you're on the right thread
// and everything Just Works(tm).
}
}
}

Windows Service and timers

I am learning creating windows services and threading. I am using a library provided by fellow worker that aids in building threaded service but this is not giving me the knowledge at the basic level.
Lets say i will have a service that will be long running (little advance than the basic example available on the net), needs to wake up every 15 seconds and then perform its action (basically will be always running). Action involves looking for a status in the DB and then performing actions.
How should the following be handled in such cases:
1. disposing the thread
2. in cases where action takes longer to execute than the interval.
I have found the following example but i am having problems with the above 2 points. Please do keep in mind that the service will be running always.
http://www.java2s.com/Tutorial/CSharp/0280__Development/CreatethedelegatethattheTimerwillcall.htm
using System;
using System.Threading;
class MainClass
{
public static void CheckTime(Object state)
{
Console.WriteLine(DateTime.Now);
}
public static void Main()
{
TimerCallback tc = new TimerCallback(CheckTime);
Timer t = new Timer(tc, null, 1000, 500);
Console.WriteLine("Press Enter to exit");
int i = Console.Read();
// clean up the resources
t.Dispose();
t = null;
}
}
So in my example, what will go in
1. stop event
2. Does start event looks good?
3. what should happen if nothing found in the queue?
4. What if the actions take longer than the interval?
public partial class QueueService : ServiceBase
{
public QueueService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
TimerCallback tc = new TimerCallback(CheckQueue);
Timer t = new Timer(tc, null, 10000, 15000); //first time wait for 10seconds and then execte every 15seconds
}
catch (Exception ex)
{
what should i be checking here and then also make sure that the threading/timer doesn't stop. It should still execute every 15 seconds
}
}
protected override void OnStop()
{
what needs to go here...
}
private static void CheckQueue(Object state)
{
... Connect to the DB
... Check status
... if queue status found then perform actions
. A
. C
. T
. I
. O
. N
. S
... if end
}
}
Thanks for looking!
Disposing the timer.
Not completely. You need to declare the timer at class level otherwise it will be collected after few iterations.
Nothing.
Stop the timer before you check the queue and start it again after you finish with it. This way you won't get into troubles of shared memory or other collisions.
public partial class QueueService : ServiceBase
{
Timer timer;
public QueueService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
TimerCallback tc = new TimerCallback(CheckQueue);
timer = new Timer(tc, null, 10000, 15000);
}
catch (Exception ex)
{
}
}
protected override void OnStop()
{
if (timer != null)
timer.Dispose();
}
private static void CheckQueue(Object state)
{
timer.Change(Timeout.Infinite, 0);
... Connect to the DB
... Check status
... if queue status found then perform actions
. A
. C
. T
. I
. O
. N
. S
... if end
timer.Change(10000, 15000);
}
}

How to implement cancellable worker thread

I'm trying to implement a cancellable worker thread using the new threading constructs in System.Threading.Tasks namespace.
So far I have have come up with this implementation:
public sealed class Scheduler
{
private CancellationTokenSource _cancellationTokenSource;
public System.Threading.Tasks.Task Worker { get; private set; }
public void Start()
{
_cancellationTokenSource = new CancellationTokenSource();
Worker = System.Threading.Tasks.Task.Factory.StartNew(
() => RunTasks(_cancellationTokenSource.Token),
_cancellationTokenSource.Token
);
}
private static void RunTasks(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
Thread.Sleep(1000); // simulate work
}
}
public void Stop()
{
try
{
_cancellationTokenSource.Cancel();
Worker.Wait(_cancellationTokenSource.Token);
}
catch (OperationCanceledException)
{
// OperationCanceledException is expected when a Task is cancelled.
}
}
}
When Stop() returns I expect Worker.Status to be TaskStatus.Canceled.
My unit tests have shown that under certain conditions Worker.Status remains set to TaskStatus.Running.
Is this a correct way to implement a cancellable worker thread?
I believe that the problem is in your call to
Worker.Wait(_cancellationTokenSource.Token);
That's waiting for the token to be signalled - which it already is, because you've just called Cancel(). If you change that to just
Worker.Wait();
then I believe you'll see a state of RanToCompletion. You won't see Canceled, because your task isn't throwing OperationCanceledException. If you change your RunTasks method to call
cancellationToken.ThrowIfCancellationRequested()
at the end, then you'll need to catch an AggregateException in Stop - but then you'll see a state of Canceled at the end.
At least, that's what my experimentation shows :)

Resources