I have the following utility:
class Worker
{
public void DoWorkAsync(Action callback)
{
Action work = () => Thread.Sleep(3000);
AsyncCallback asyncCallback = (result) => callback();
work.BeginInvoke(asyncCallback, null);
}
}
I use it like the following:
static void Main(string[] args)
{
var worker = new Worker();
worker.DoWorkAsync(() => Console.WriteLine("Completed."));
Console.WriteLine("Hello world!");
Console.ReadKey();
}
This will of course print Hello world! before Completed., since the worker works asynchronously.
My question is how can I block my thread so it should wait until the action is completed, then move on.
I know I can do it like this:
static void Main(string[] args)
{
var worker = new Worker();
worker.DoWorkAsync(() =>
{
Console.WriteLine("Completed.");
MoveOn();
});
Console.ReadKey();
}
static void MoveOn()
{
Console.WriteLine("Hello world!");
}
But since I have a bunch of cascaded async callbacks that should be executed one after the other (conditionally), I want them all to execute synchronously, so is there a more elegant way to wait for an async method that takes a callback as a param?
Note: Just to make sure, I cannot alter the behavior of the Worker class, its an external utility and I don't have access to its code.
Update
In my particular scenario I'm trying to interact with user from the ViewModel and get responses from him. My code is executed in the view-model and there is a method controlling a chain of cascaded interactions, I want this method should decide whether to fire a certain interaction or not. I tried SLaxs' answer, and also tried this but it doesn't seem to work, any ideas on how to make the main method the only controller of the interactions?
Create a ManualResetEvent, call Set() in the callback, and call WaitOne() to wait for the operation to finish.
Related
I have one situation.
I have one Eclipse job with following code:
private class ExecutionJob extends Job {
public static final String MY_FAMILY = "myJobFamily";
public ExecutionJob(String name) {
super(name);
}
#Override
protected IStatus run(IProgressMonitor monitor) {
monitor.beginTask("executing ...... ", IProgressMonitor.UNKNOWN);
methodForExecution();
monitor.done();
return Status.OK_STATUS;
}
#Override
public boolean belongsTo(Object family) {
return family == MY_FAMILY;
}
}
And this methodForExecution() has code as below :
public void methodForExecution(){
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView("view_id");
}
Now, the situation is, job opens up something like progressmonitor, and my method is trying to access UI which is actually behind this job's progressmonitor. And it gives NullPointerException as the progress monitor does not have ActiveWorkbenchWindow.
I can not use UIJob, as I have to execute this methodForExecution() asynchronously.
Can someone please help me resolving this.
The code you want to run must run in the UI thead.
If most of the work in the job is updating the UI and there is no long running non-UI code then you should use UIJob to run this. This is still scheduled as a job but the runInUIThread method is executed in the UI thread.
If you have a lot of non-UI code especially long running code then use a normal Job but you will have to use Display.asyncExec to run the method in the UI thread:
Display.getDefault().asyncExec(new Runnable()
{
#Override
public void run()
{
methodForExecution();
}
});
In Java 8 you could do:
Display.getDefault().asyncExec(this::methodForExecution);
You can also use syncExec instead of asyncExec to wait for the UI to update.
If the showView is all you want to do you could just do the asyncExec without using a Job.
I'd like to create an Esper engine long running process but I'm not sure of Esper's threading model nor the model I should implement to do this. Naively I tried the following:
public class EsperTest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
//EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider();
EPServiceProvider epService = EPServiceProviderManager.getProvider("CoreEngine");
epService.addServiceStateListener(new EPServiceStateListener() {
#Override
public void onEPServiceDestroyRequested(EPServiceProvider epsp) {
System.out.println("Service destroyed");
}
#Override
public void onEPServiceInitialized(EPServiceProvider epsp) {
System.out.println("System initialised");
}
});
epService.initialize();
}
}
But the code appears to execute to the end of the main() method and the JVM ends.
Referring to the Esper documentation, section 14.7 p456:
In the default configuration, each engine instance maintains a single timer thread (internal timer)
providing for time or schedule-based processing within the engine. The default resolution at which
the internal timer operates is 100 milliseconds. The internal timer thread can be disabled and
applications can instead send external time events to an engine instance to perform timer or
scheduled processing at the resolution required by an application.
Consequently I thought that by creating a an engine instance ("CoreEngine") at least one (timer) thread would be created and assuming this is not a daemon thread the main() method would not complete but this appears not to be the case.
Do I have to implement my own infinite loop in main() or is there a configuration which can be provided to Esper which will allow it to run 'forever.?
The timer threads is a daemon thread.
Instead of a loop use a latch like this.
final CountDownLatch shutdownLatch = new CountDownLatch(1);
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
shutdownLatch.countDown();
}
});
shutdownLatch.await();
I'm maintaining software that contains a bunch of user groups. When an Admin clicks "Remove" on a user of a group, two things should happen:
delete the group member (involves updating cache, db, etc.)
reload a list of group members (the user sees this list when he/she deletes a user)
It turns out that #2 finishes before #1 - race condition. As a result, I want to add a callback so that #2 does not execute until #1 is successful.
Is this code acceptable for GWT to ensure #2 occurs before #1?
doTask1();
GWT.runAsync(new RunAsyncCallback()
{
public void onFailure(final Throwable reason)
{
}
public void onSuccess()
{
doTask2();
}
});
GWT#runAsync() is used for GWT's "code splitting" feature, which allows deferred loading of code (and other runtime resources) until they are needed. You need to use GWT's asynchronous operation patterns (i.e. AsyncCallback or Command) to pass a callback to doTask1() that is invoked once the asynchronous operations there complete. For example, if doTask1() executes a GWT RPC method:
public void doTask1(final Command onCompletion) {
myRpcService.doTask1(new AsyncCallback<Void>() {
#Override
public void onFailure(Throwable caught) {
// Error handling
}
#Override
public void onSuccess(Void ignored) {
onCompletion.execute();
}
});
}
public void doTask2() {
// Perform task 2
}
public void doTasks1And2() {
doTask1(new Command() {
#Override
public void execute() {
doTask2();
}
});
}
No, you can still have a race condition with that style of control flow. Instead, you want something like this:
doTask1(new MyCallback() {
public void onTask1Complete() {
doTask2();
}
}
doTask1() needs to accept a callback so that once it is complete, it will execute the next operation.
To see why, let's assume that both doTask1() and doTask2() are making HTTP calls. You have no guarantee what order the server might receive these two connections unless you wait until the doTask1()'s request has returned . In your example code, you make the request in doTask1() (which immediately returns while the request is asynchronously made), and then make the second call without waiting for the first.
I remember that we cannot kill the current running Quartz Job but we can interrupt and have a boolean check wherever is necessary whether we need to proceed further with the subsequent operations or not.
Even when we implement the InterruptableJob and call the scheduler.interrupt to interrupt the Job, the current executed job will be still running in the server.
Ex:
A named SQL query has been triggered by the job via Hibernate which takes a long time
A call has been made to a third party server where the third party server takes a long time to respond
http://neopatel.blogspot.in/2011/05/quartz-stop-job.html
http://forums.terracotta.org/forums/posts/list/3191.page
Could someone corrects my understanding and explain me how we can kill or stop the "currently" executing Job ?
you can create new abstract class called JobBase for example that implements IJob interface and insert abstract method:
public abstract void ExecuteJob(IJobExecutionContext context);
On JobBase you can implements method Execute like this
public abstract class JobBase : IJob,IInterruptableJob
{
private Thread currentThread;
private ILog logger;
public JobBase(ILog logger)
{
this.logger=logger;
}
public void Execute(IJobExecutionContext context)
{
var thread = new Thread(()=>
{
try
{
this.ExecuteJob(context);
}
catch(Exception ex)
{
this.logger.ErrorFormat("Unhandled exception {0}",ex.ToString());
}
});
thread.Start();
this.currentThread = thread;
this.currentThread.Join();
}
public abstract void ExecuteJob(IJobExecutionContext context);
public void Interrupt()
{
currentThread.Abort();
}
}
Each Job will implements JobExecute method.
public class TestJob :JobBase
{
private ILog logger;
public TeJob(ILog logger):base(logger)
{
}
public override ExecuteJob(IJobExecutionContext context)
{
}
}
Assumes that use some factory for creating a Job
For Stopping a Job you will call method scheduler.Interrupt(new JobKey(jobName));
As you told, there is no way to interrupt "brutally" a job in quartz, neither in JAVA.
You can encapsulate your job's logic in a separate Thread and run it with the ExecutorService.
Take a look to this example: https://stackoverflow.com/a/2275596/1517816
Assume your QuartzJob is the Test class and move your business logic in the Task class.
Hope it helps
I don't know why nobody mentioned this, or maybe this was not available at the time the question was asked.
There is a method called shutdown for a Scheduler instance.
SchedulerFactory factory = new StdSchedulerFactor();
Scheduler scheduler = factory.getScheduler();
The above is used to start a job like
scheduler.start();
Use a flag or something to know when to stop the job from running. Then use
scheduler.shutdown();
How I implemented my requirement:
if(flag==true)
{
scheduler.start();
scheduler.scheduleJob(jobDetail, simpleTrigger);
}
else if(flag==false)
{
scheduler.shutdown();
}
Where jobDetail and simpleTrigger are self explanatory.
Hope it helps. :)
I need to do method interception for the onSuccess method in GWT.
I need to add some code before and after the calling of the onSuccess method in GWT? (I have many calls to the onSuccess method and I need to do this dynamically)
EDIT:
I need to add a progress bar in the right corner of the screen, that appears when the code enters the onsuccess method and disappears on the exit of onsuccess method.
From a visual perspective
void onSuccess(Value v) {
showProgressBar();
doLotsOfWork(v);
hideProgressBar();
}
will be a no-op. Browsers typically wait for event handlers to finish executing before re-rending the DOM. If the doLotsOfWork() method takes a noticeable amount of time to execute (e.g. >100ms) the user will notice the browser hiccup due to the single-threaded nature of JavaScript execution.
Instead, consider using an incrementally-scheduled command to break the work up. It would look roughly like:
void onSuccess(Value v) {
showProgressBar();
Scheduler.get().scheduleIncremental(new RepeatingCommand() {
int count = 0;
int size = v.getElements().size();
public boolean execute() {
if (count == size) {
hideProgressBar();
return false;
}
processOneElement(v.getElements().get(count++));
setProgressBar((double) count / size);
return true;
}
});
}
By breaking the work across multiple pumps of the browser's event loop, you avoid the situation where the webapp becomes non-responsive if there's a non-trivial amount of work to do.
Well, it is a generic non-functional requirement, I have done some research on this item, I have implemented a solution that Thomas Broyer has suggested on gwt group.. This solution has distinct advantage over other suggested solutions, You dont have to change your callback classes, what you have to do is just add a line of code after creation of async gwt-rpc service...
IGwtPersistenceEngineRPCAsync persistenceEngine = GWT.create(IGwtPersistenceEngineRPC.class);
((ServiceDefTarget) persistenceEngine).setRpcRequestBuilder(new ProgressRequestBuilder());
import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.rpc.RpcRequestBuilder;
public class ProgressRequestBuilder extends RpcRequestBuilder {
private class RequestCallbackWrapper implements RequestCallback {
private RequestCallback callback;
RequestCallbackWrapper(RequestCallback aCallback) {
this.callback = aCallback;
}
#Override
public void onResponseReceived(Request request, Response response) {
Log.debug("onResposenReceived is called");
// put the code to hide your progress bar
callback.onResponseReceived(request, response);
}
#Override
public void onError(Request request, Throwable exception) {
Log.error("onError is called",new Exception(exception));
// put the code to hide your progress bar
callback.onError(request, exception);
}
}
#Override
protected RequestBuilder doCreate(String serviceEntryPoint) {
RequestBuilder rb = super.doCreate(serviceEntryPoint);
// put the code to show your progress bar
return rb;
}
#Override
protected void doFinish(RequestBuilder rb) {
super.doFinish(rb);
rb.setCallback(new RequestCallbackWrapper(rb.getCallback()));
}
}
You cant do that. The rpc onSuccess() method runs asynchronously (in other words, depends on the server when it completes, the app doesnt wait for it). You could fire code immediately after the rpc call which may/ may not complete before the onSuccess for RPC calls.
Can you explain with an eg why exactly do u want to do that? Chances are you might have to redesign the app due to this async behavior, but cant say till you provide a use case. Preferably any Async functionality should be forgotten after the rpc call, and actioned upon only in the onSuccess.