Is there a way to do a "wait()" on the javafx thread that pauses the execution of a method until a background task finishes but allowing the javafx thread to continue.
I have found a propietary method to do something like this
Toolkit.getToolkit().enterNestedEventLoop(key);
and
Toolkit.getToolkit().exitNestedEventLoop(key, value);
Imagine that you have an #FXML action method when the user clicks a button and inside that method (running on the FX Thread) I want to do the following:
1 get a value from a javafx observable property
2 disable an area of the screen and display a progress indicator
3 call a long running task on a server and stop the excution of the action method here without blocking the UI (or in other words, letting the user navigate to another screen while the background task runs)
4 continue here on the fx thread reenabling the ui and hiding the progress indicator
5 update the UI with values returned from the server.
I know one can use a javafx Task to achieve a similar thing, but that would require moving 4 and 5 to the suceeded() method of the javafx task and that is not what i want.
We've got a framework which allows the developer to annotate some of the remote service stubs on a javafx controller with a #Background annotation and replaces those stubs with a jdk dynamic proxy which switches all invocations to any method in the stubs to run on a non javafx thread and continue on 4 when the server call has finished so we don't have to fill up our code with javafx thread synchronization code.
The Toolkit.getToolkit().enterNestedEventLoop(key); and Toolkit.getToolkit().exitNestedEventLoop(key, value); work well in most cases, except in some scenarios like:
if the invocation happens on the javafx thread at application startup time (prepopulating a screen with server data on startup)
if a #FXML action method has two server calls in the same method
Related
In Spring MVC, I have to run a function continuously in a controller until user terminates it also I have to maintain progress on UI simultaneously. I did the first part i.e. continuously run function using ExecutorService but I am not getting how to sync it with UI to show progress.
Currently what happening is as soon as I run that controller the view is returned and ExecutorService keeps running in background, I have to return the view only if the user terminates the operation.
Does JavaFX's AnimationTimer run on a separate thread when launched?
I ran a JavaFX application in a debugger, with and without a AnimationTimer, and in both cases there were 6 threads running. Plus, the JavaDocs don't mention it implementing Runnable.
That suggests that it's not run in its own thread, but by its very nature, I'd think it would need to run in its own thread to ensure it runs in a regular enough schedule.
And if it's not run in its own thread, is it just run in whatever thread creates it? Does that mean it's safe to modify UI elements from within the Timer if I create the AnimationTimer inside of Application's start()?
Does JavaFX's AnimationTimer run on a separate thread when launched?
No, it doesn't. It runs on the JavaFX application thread. The AnimationTimer's handle() method is called in every frame while the AnimationTimer is active. Normally, JavaFX tries to maintain a frame rate of 60 fps.
Does that mean it's safe to modify UI elements from within the Timer if I create the AnimationTimer inside of Application's start()?
Yes, it is. Since it runs on the JavaFX application thread, it is perfectly fine to modify scene graph elements. Just make sure you are not doing heavy computation in the handle().
I have a childwindow with an associated VM that gets created each time I ask the child window to open. when the childwindow opens, it registers a listener for an MVVM Light message. After I close the window, I'm pretty sure that I'm releasing all references to it, but I don't actually call dispose because it does not implement IDisposeable.
When I instanciate another child window of the same type, and send it a different context, I know that I'm receiving the message from the previous instanciation of the VM... each time I use the window, more and more VM are listening, and the code repeats.
How can I be sure that my previous VM that registered to listen to a message, has actually been released and is no longer active. Is there a deterministic way to do this?
Whenever you register a message you should make sure that you unregister the message as well. To unregister you can use Cleanup method on classes deriving from ViewModelBase. In other cases, e.g. a view, you should implement a method hat is called when the view is unloaded - e.g by trapping and handling the unloaded event on a control or view. In this method you then call Messenger.Unregister(EventTarget).
This behaviour is a quirk in the current version of the toolkit, and Laurent is aware of it.
How have you coded the handler for the message in the VM? It sounds like you're probably pointing it to a method inside the same VM which is registering for the message. This causes the Messenger class to maintain a reference to the VM and prevent it's garbage collection (see here for discussion). There are two solutions: implement IDisposable and unregister all messages for your VM instance or simply unregister all messages from the VM instance when the child dialog closes. Personally I'd do both to ensure the entire object web is released.
You can use either the Cleanup method or manually unregister the message. For more details click here.
NativeApplication.nativeApplication.exit(); - this method is used for exit the application of flex/air .
application.close(); - this method also used for exit the application of flex/air -
So what is different?
He is referring to NativeApplication.exit() vs WindowedApplication.close().
WindowedApplication.close() Closes the
application's NativeWindow (the
initial native window opened by the
application). This action is
cancelable.
Calling close() on the application window will effectively shut down the application, but using the exit() method on NativeApplication is the proper way to terminate it. See the following link for more info:
http://livedocs.adobe.com/flex/3/html/help.html?content=app_launch_1.html
I am not sure I am understanding your question entirely because I am not finding an application.close() method.
Here is the documentation on NativeApplication, an AIR only class: http://livedocs.adobe.com/flex/3/langref/flash/desktop/NativeApplication.html#exit()
It defines the exit method like this:
Terminates this application.
The call to the exit() method will
return; the shutdown sequence does not
begin until the currently executing
code (such as a current event handler)
has completed. Pending asynchronous
operations are canceled and may or may
not complete.
Note that an exiting event is not
dispatched. If an exiting event is
required by application logic, call
NativeApplication.nativeApplication.dispatchEvent(),
passing in an Event object of type
exiting. Likewise, closing and close
events are not dispatched before
application windows are closed. If
windows should be notified before your
application exits, you can dispatch
closing events for each open window.
If a window close event is required,
call the window's close() method
before exiting.
Here is the documetation on Application, a Flex class: http://livedocs.adobe.com/flex/3/langref/mx/core/Application.html#methodSummary
It does not seem to have a close() method associated with it. Are you possibly confusing the application class with a window class that you need to close before calling the NativeApplication.nativeApplication.exit() ?
I would be happy to help you research this further if you can clarify the question.
One completely exits the application, the other only closes the main window. It's important to understand the difference. On a Mac, for instance, closing all of an application's windows often leaves that application running in the dock. This is rarely the case on Windows, but if you have a dock icon, you should get similar behavior, I think.
I am writing a custom Windows Workflow Foundation activity, that starts some process asynchronously, and then should wake up when an async event arrives.
All the samples I’ve found (e.g. this one by Kirk Evans) involve a custom workflow service, that does most of the work, and then posts an event to the activity-created queue. The main reason for that seems to be that the only method to post an event [that works from a non-WF thread] is WorkflowInstance.EnqueueItem, and the activities don’t have access to workflow instances, so they can't post events (from non-WF thread where I receive the result of async operation).
I don't like this design, as this splits functionality into two pieces, and requires adding a service to a host when a new activity type is added. Ugly.
So I wrote the following generic service that I call from the activity’s async event handler, and that can reused by various async activities (error handling omitted):
class WorkflowEnqueuerService : WorkflowRuntimeService
{
public void EnqueueItem(Guid workflowInstanceId, IComparable queueId, object item)
{
this.Runtime.GetWorkflow(workflowInstanceId).EnqueueItem(queueId, item, null, null);
}
}
Now in the activity code, I can obtain and store a reference to this service, start my async operation, an when it completes, use this service to post an event to my queue. The benefits of this - I keep all the activity-specific code inside activity, and I don't have to add new services for each activity types.
But seeing the official and internet samples doing it will specialized non-reusable services, I would like to check if this approach is OK, or I’m creating some problems here?
There is a potential problem here with regard to workflow persistence.
If you create long running worklfows that are persisted in a database to the runtime will be able to restart these workflows are not reloaded into memory until there is some external event that reloads them. As there they are responsible for triggering the event themselves but cannot until they are reloaded. And we have a catch 22 :-(
The proper way to do this is using an external service. And while this might feel like dividing the code into two places it really isn't. The reason is that the workflow is responsible for the big picture, IE what should be done. And the runtime service is responsible for the actual implementation or how it should be done. That way you can change the how without changing the why and when part.
A followup - regardless of all the reasons, why it "should be done" using a service, this will be directly supported by .NET 4.0, which provides a clean way for an activity to start an asynchronous work, while suspending the persistence of the activity.
See
http://msdn.microsoft.com/en-us/library/system.activities.codeactivitycontext.setupasyncoperationblock(VS.100).aspx
for details.