easyWorker
easyWorker copied to clipboard
How can reuse a thred
I have to create worker and use it in a
SQLConnection. So the multiple worker solution is not good for me.
How can I use again a thread, when it's result event is dispatched?
If I trace the state of the thread in the event handler method, the result is: started
... in a SQLConnection ? can you please detailed for use case, thanks.
DatabaseControllerWorker.as
/**
* Created by varadig on 1/30/16.
*/
package controller.database {
import com.doublefx.as3.thread.Thread;
import com.doublefx.as3.thread.api.IThread;
import com.doublefx.as3.thread.event.ThreadFaultEvent;
import com.doublefx.as3.thread.event.ThreadResultEvent;
import controller.database.base.BaseDatabaseController;
import controller.database.interfaces.IDatabaseController;
import controller.database.workers.DatabaseWorker;
import flash.filesystem.File;
import model.database.DatabaseFile;
import model.geolocation.route.CyclingRoute;
import model.geolocation.route.WalkingRoute;
import model.geolocation.route.base.BaseRoute;
import model.geolocation.route.interfaces.IRoute;
import starling.core.Starling;
public class DatabaseControllerWorker extends BaseDatabaseController implements IDatabaseController {
private var thread:IThread;
public function DatabaseControllerWorker() {
super();
this.initThreads();
}
private function initThreads():void {
Thread.DEFAULT_LOADER_INFO = Starling.current.nativeStage.loaderInfo;
this.thread = new Thread(DatabaseWorker, "databaseWorker", true, DatabaseWorker.DEPENDENCIES);
this.thread.addEventListener(ThreadResultEvent.RESULT, thread_resultHandler);
this.thread.addEventListener(ThreadFaultEvent.FAULT, thread_faultHandler);
}
private function thread_resultHandler(event:ThreadResultEvent):void {
log('thread result: ' + event.result);
}
private function thread_faultHandler(event:ThreadFaultEvent):void {
log('thread fault');
}
public function open(file:DatabaseFile):void {
this.thread.start('open', DatabaseFile(file));
}
public function read():void {
thread.start('read');
}
public function updateRoute(route:IRoute):void {
if (!this.isOppened)
return;
var walkingDistance = (route is WalkingRoute) ? int(BaseRoute(route).distanceInMeter) : 0;
var cyclingDistance = (route is CyclingRoute) ? int(BaseRoute(route).distanceInMeter) : 0;
this.commitData(walkingDistance, cyclingDistance);
}
public function updateRoutes(routes:Vector.<IRoute>):void {
if (!this.isOppened)
return;
var walkingDistance = 0;
var cyclingDistance = 0;
for each(var route:IRoute in routes) {
if (route is WalkingRoute)
walkingDistance += int(BaseRoute(route).distanceInMeter);
if (route is CyclingRoute)
cyclingDistance += int(BaseRoute(route).distanceInMeter);
}
this.commitData(walkingDistance, cyclingDistance);
}
public function commitData(walking:int, cycling:int):void {
this.thread.start('update', walking, cycling, this.currentDay);
}
public function close():void {
this.thread.start('close');
}
public function save(file:File):void {
}
}
}
DatabaseWorker.as
/**
* Created by varadig on 1/29/16.
*/
package controller.database.workers {
import com.doublefx.as3.thread.api.CrossThreadDispatcher;
import com.doublefx.as3.thread.api.Runnable;
import com.doublefx.as3.thread.event.ThreadActionRequestEvent;
import com.doublefx.as3.thread.event.ThreadActionResponseEvent;
import core.base.CoreBaseClass;
import flash.data.SQLConnection;
import flash.data.SQLStatement;
import flash.events.SQLEvent;
import model.database.DatabaseFile;
import model.database.SQL;
public class DatabaseWorker extends CoreBaseClass implements Runnable {
/**
* Mandatory declaration if you want your Worker be able to communicate.
* This CrossThreadDispatcher is injected at runtime.
*/
private var _dispatcher:CrossThreadDispatcher;
private var connection:SQLConnection;
public static const READ:String = 'database.worker.read';
public static const UPDATE:String = 'database.worker.update';
public static const DEPENDENCIES:Vector.<String> = Vector.<String>([
"controller.database.*",
'core.notification::CoreNotification',
'core.base::CoreBaseClassFactory',
'model.database.*',
'model.settings.*',
'model.geolocation.*',
'flash.data.SQLResult',
'com.probertson.*']);
public function DatabaseWorker():void {
super();
}
public function run(args:Array):void {
var message:String = args[0];
switch (message) {
case 'open':
this.open(args[1]);
break;
case 'read':
this.read();
break;
}
return;
}
private function open(file:DatabaseFile):void {
this.connection = new SQLConnection();
this.connection.open(file);
dispatcher.dispatchResult('opened');
}
private function read():void {
var readStatement:SQLStatement = new SQLStatement();
readStatement.sqlConnection = this.connection;
readStatement.text = SQL.getInstance().SELECT_ALL_DISTANCE;
readStatement.addEventListener(SQLEvent.RESULT, function (event:SQLEvent) {
dispatcher.dispatchResult('read');
});
readStatement.execute();
}
public function get dispatcher():CrossThreadDispatcher {
return _dispatcher;
}
public function set dispatcher(value:CrossThreadDispatcher):void {
_dispatcher = value;
if (_dispatcher) {
_dispatcher.addEventListener(ThreadActionRequestEvent.PAUSE_REQUESTED, dispatcher_pauseRequestedHandler);
_dispatcher.addEventListener(ThreadActionRequestEvent.RESUME_REQUESTED, dispatcher_resumeRequestedHandler);
_dispatcher.addEventListener(ThreadActionRequestEvent.TERMINATE_REQUESTED, dispatcher_terminateRequestedHandler);
}
}
// Won't be call if IThread.pause() has been called before start();
private function dispatcher_pauseRequestedHandler(event:ThreadActionRequestEvent):void {
trace("Pause requested, I do the eventual job to before Paused...");
_dispatcher.dispatchEvent(new ThreadActionResponseEvent(ThreadActionResponseEvent.PAUSED));
}
// Won't be call if IThread.resume() has been called before start();
private function dispatcher_resumeRequestedHandler(event:ThreadActionRequestEvent):void {
trace("Resume requested, I do the eventual job to before Resumed...");
_dispatcher.dispatchEvent(new ThreadActionResponseEvent(ThreadActionResponseEvent.RESUMED));
}
// Won't be call if IThread.terminate() has been called before start();
private function dispatcher_terminateRequestedHandler(event:ThreadActionRequestEvent):void {
trace("Terminate requested, I do the eventual job to before Terminated...");
_dispatcher.dispatchEvent(new ThreadActionResponseEvent(ThreadActionResponseEvent.TERMINATED));
}
}
}
If call method open in the DatabaseControllerWorker class, the thread is dispatch the result: open But after if I wanted to read the database (or call/start anything in the thread) nothing happend. No result no fault.
Yeah, workers have been designed to have 1 entry point and once it has executed its supposed "long CPU consuming task", it terminates itself, I did not change the original design but I guess I could add a wait() method accessible from the Runnable as it can be already achieve with Mutex and Condition.
Thanks doublefx, It would be very nice