Read from some article(s), that the Parallel Activity doesn't execute the child activities in different threads until and unless the child activities themselves are asynchronous.
So I just built a custom AsyncCodeActivity named AsyncTask which has an Activity(named SyncActivity) as InArgument and within the BeginExecute I call Task.Factory.StartNew(() => WorkflowInvoker(SyncActivity)).
But I also want a designer which would look exactly similar to the Parallel Activity and have same functionalities(like dragging some activity and putting it in one of the branches) as Parallel Activity.But when some Activity is dragged and dropped into one of the branches, it should internally run asynchronously using the AsyncTask AsyncActivity.
How do I do that?
I understand your problem. Building an activity designer (control in WF) is not that hard. Just use the WorkflowItemPresenter like shown on MSDN.
To fulfill your further requirements we have to keep in mind that activities take parameters. You have to pass them to your SyncActivity through the outer AsyncActivity. Therefore you have to enhance your activity designer by dynamically created input controls. To create those you need to access the public properties of your SyncActivity (e. g. by Reflection). I found it hard to even access the inner activity, because you have to work yourself through a so called "ModelItem".
An easier approach might be passing the parameters by creating a chain of variables.
And by the way: The task factory helps you creating tasks, but it doesn't force the creation of new threads. Just keep the task/thread model in mind ;-)
Regards
Jan
Related
I am writing an Adobe AIR application using PureMVC.
Imagine that I have an page-based application view ( using ViewStack ), and user is navigating through this pages in some way ( like clicking the button or whatever ).
Now for example I have an Account Infromation page which when instantiated or showed again needs to load the data from WebService ( for example email, account balance and username ), and when the data is returned I want to show it on my Account Information page in the proper labels.
The problem is when I will execute this three Web Calls, each of them will return different resultEvent at different time. I am wondering what is the best way to get the information that ALL of the service calls returned results, so I know that I can finally show all the results at once ( and maybe before this happens play some loading screen ).
I really don't know much about PureMVC, but the as3commons-async library is great for managing async calls and should work just fine in any framework-setup
http://as3commons.org/as3-commons-async/
In your case, you could create 3 classes implementing IOperation or IAsyncCommand (depending on if you plan to execute the operations immediately or deferred) encapsulating your RPCs.
After that is done you simply create a new CompositeCommand and add the operations to its queue.
When all is done, CompositeCommand will fire an OperationEvent.COMPLETE
BTW, the library even includes some pre-implemented common Flex Operations, such as HTTPRequest, when you download the as3commons-asyc-flex package as well.
I would do it in this way:
Create a proxy for each of three information entities (EMailProxy, BalanceProxy, UsernameProxy);
Create a delegate class which handles the interaction with your WebService (something like "public class WSConnector implements IResponder{...}"), which is used by the proxies to call the end ws-methods;
Create a proxy which coordinates all the three results (CoordProxy);
Choose a mediator which will coordinate all the three calls (for example it could be done by your ApplicationMediator);
Create notification constants for all proxy results (GET_EMAIL_RESULT, GET_BALANCE_RESULT, GET_USERNAME_RESULT, COORD_RESULT);
Let the ApplicationMediator get all 4 notifications;
it is important that you should not only wait for all three results but also be ready for some errors and their interpretation. That is why a simple counter could be too weak.
The overall workflow could look like this:
The user initiates the process;
Some mediator gets an event from your GUI-component and sends a notification like DO_TRIPLECALL;
The ApplicationMediator catches this notification, drops the state of the CoordProxy and calls all 3 methods from your proxies (getEMail, getBalance, getUsername).
The responses are coming asynchronously. Each proxy gets its response from the delegate, changes its own data object and sends an appropriate notification.
The ApplicationMediator catches those notifications and changes the state of the CoordProxy. When all three responses are there (may be not all are successful) the CoordProxy sends a notification with the overall result.
I know it is not the best approach to do such an interaction through mediators. The initial idea was to use commands for all "business logic" decisions. But it can be too boring to create the bureaucracy.
I hope it can help you. I would be glad to know your solution and discuss it here.
If you have a lot of small classes (that are often created and destroyed), and they all depend on the settings, how would you do that?
It would be nice not to have to connect each one to some kind of "settings changed" signal, and even if I did, all the settings will be updated, even those objects whose settings didn't change.
When faced with that myself, I've found it's better to control the save/load settings from a central place. Do you really need to save/load the settings on a regular basis or can you have a master object (likely with a list of the sub-objects) control when savings actually need to be done? Or, worst case, as the objects are created and destroyed have them update an in-memory setting map in the parent collection and save when it thinks it should be saved, rather than child object destruction.
One way of implementing it is given below.
If you wish, the central location for the settings can be a singleton derived from QAbstractItemModel, and you can easily connect the dataChanged(...) signal to various objects as necessary, to receive notifications about changed settings. Those objects can decide whether an applicable setting was changed. By judicious use of helper and shim classes, you can make it very easy to connect your "small classes" with notifications. This would address two issues inherent in the model driven approach to settings.
The possibly large number of subscribers, all receiving notifications about the settings they usually don't care about (the filtering issue).
The extra code needed to connect the subscriber with the item model, and the duplication of information as to what indices of the model are relevant (the selection issue).
Both filtering and selection can be dealt with by a shim class that receives all of the dataChanged notifications, and for each useful index maintains a list of subscribers. Only the slots of the "interested" objects would then be invoked. This class would maintain the list of subscriber-slot pairs on its own, without offering any signals for others to connect to. It'd use invokeMethod or a similar mechanism to invoke the slots.
The selection issue can be dealt with by observing that the subscriber classes will, upon initialization, query the model for initial values of all of the settings that affect their operation - that they are "interested" in. All you need is a temporary proxy model that you create for the duration of the initialization of the subscriber. The proxy model takes the QObject* instance of the caller, and records all of the model indices that were queried (passing them onto the singleton settings model). When the proxy model is finally destroyed at the return from the initialization of the subscriber class, it feeds the information about the model indices for this QObject to the singleton. A single additional call is needed to let the singleton know about the slot to call, but that's just like calling connect().
What I typically do is to create a class handling all my settings, with one instance per thread. To make it quicker to write this class, I implemented a couple of macros that let me define it like this:
L_DECLARE_SETTINGS(LSettingsTest, new QSettings("settings.ini", QSettings::IniFormat))
L_DEFINE_VALUE(QString, string1, QString("string1"))
L_DEFINE_VALUE(QSize, size, QSize(100, 100))
L_DEFINE_VALUE(double, temperature, -1)
L_DEFINE_VALUE(QByteArray, image, QByteArray())
L_END_CLASS
This class can be instantiated once per thread and then used without writing anything to the file. A particular instance of this class, returned from LSettingsTest::notifier(), emits signals when each property changes. If exposed to QML, each property work as regular Qt property and can be assigned, read and used in bindings.
I wrote more info here. This is the GitHub repo where I placed the macros.
On occasion, I have wanted to push a closure onto ActionScript's event stack so that it will be executed after the current event handler. Right now I use setTimeout(closure, 0). Is there a more direct way of doing this?
setTimeout(closure, 0) is creating a new event stack. I don't understand your objective if this solution isn't working for you. What is the goal you're trying to accomplish?
Flex has ENTER_FRAME events, Timer, callLater, setTimeout, setInterval, all which delay calls and create new execution stacks.
Are you trying to inject code into the current stack? If so, you might need to look at something like this: http://en.wikipedia.org/wiki/Active_object. The idea being that you push functions (closures) into an array, and the active object controller pulls the next one off the list when the previous one has run to completion. That's the simplest case. You can write a more complicated one that will have priority stacks like high, medium, low, with your own schedule management system. (e.g., low get promoted after waiting too long).
But hey! The devil is in the details. What's the goal?
Take a look at capture and bubbling phases of the as3 events.
I found this nice chapter that explains clearly the proccess: http://books.google.com/books?id=yFNZGjqJe9IC&lpg=PA250&ots=oPB9HXIby7&dq=flash%20event%20bubbling%20phase&pg=PA250#v=onepage&q=&f=false
And also check the EventDispatcher class documentation that explain the use of this different phases.
Until recently I have been using cairngorm as a framework for flex. However, in this latest project I have switched to Mate. It's` still confusing me a little as I kind of got used to leaving data in the model. I have a couple of components which rely on the same dataset(collection).
In the component the creation complete handler sends a 'GiveMeMyDataEvent' which is caught by one of the eventmaps. Now in cairngorm in my command class I would have had a quick peek in the model to decide whether I need to get the data from the server or not and then either returned the data from the model or called the db.
How would I do this in Mate? Or is there a better way to go about this, I'm trying to utilize the data that has already been recieved from the server, but at the same time I'm not sure I have loaded the data or not. If a component which uses that same data has been instantiated then the answer is yes otherwise no.
Any help/hints greatly appreciated.
Most things in Mate are indirect. You have managers that manage your data, and you set up injectors (which are bindings) between the managers and your views. The injectors make sure your views are synchronized with your managers. That way the views always have the latest data. Views don't get updated as a direct consequence of dispatching an event, but as an indirect consequence.
When you want to load new data you dispatch an event which is caught by an event map, which in turn calls some service, which loads data and returns it to the event map, and the event map sticks it into the appropriate manager.
When the manager gets updated the injectors make sure that the views are updated.
By using injectors you are guaranteed to always have the latest data in your views, so if the views have data the data is loaded -- unless you need to update periodically, in which case it's up to you to determine if data is stale and dispatch an event that triggers a service call, which triggers an update, which triggers the injectors to push the new data into the views again, and round it goes.
So, in short the answer to your question is that you need to make sure you use injectors properly. If this is a too high-level answer for you I know you can get more help in the Mate forums.
I ran into a similiar situation with the app I am working on at the moment, and found that it is easily implemented in Mate when you start thinking about having two events.
The first event being something like DataEvent.REFRESH_MY_DATA. This event is handled by some DataManager, which can decide to either ignore it (since data is already present in the client and considered up to date), or the manager can dispatch an event like DataEvent.FETCH_MY_DATA.
The FETCH_MY_DATA event triggers a service call in the event map, which updates a value in the manager. This update is property-injected into the view, happy days :)
I guess it's quite a common problem in databinding scenarios.
What do you usually do, if you are running a batch update and want to avoid that a propertychanged-dependend calculations/actions/whatever are executed for every single update?
The first thing which usually comes to my mind, is to either introduces a new boolean or unhook/hook the eventhandler, ...
What I don't like about this approaches is:
they introduce new complexity (has to be maintained, ...)
they are error prone, because you have to make sure that a suppressed notifications are sent afterwards
I'm wondering if somebody addressed this problem already in a more convenient way that is more easy to handle?
tia
Martin
Edit: not to missunderstand me. I know about the things .NET provides like RaiseListChangedEvents from BindingList, ... They are all addressing the problem in more/less the same way as I described, but I'm searching for a different way which doesn't have to listed drawbacks.
Maybe I'm on the wrong track, but I though I give it a try here...
There isn't a single one-size-fits-all solution, unfortunately. I've applied or seen the following solutions:
There are two singals. One signal is emitted when the change comes from a user action, the other always fires. This allows to distinguish between changes in the UI and updates by code.
A boolean to protect code
The property event framework stops propagating events automatically when a value didn't really change.
A freeze/thaw method on the signal or the signal manager (i.e. the whole framework)
A way to merge signals into a single one. You can do N updates and they get collected into M signals where M <= N. If you change the same property 100 times, you still only get 1 signal.
Queuing of signals (instead of synchronous execution). The queuing code can then merge signals, too. I've used this with great success in an application that doesn't have a "Save" button. All changes are saved to the database as you make them. When you change a text, the changes are merged over a certain time (namely until the previous DB update returns) and then, they are committed as a single change.
An API to set several values at once; only a single signal is emitted.
The signal framework can send signals at different levels of granularity. Say you have a person with a name. When you change the name, you get two signals: One for the name change and one "instance field changed". So if you only care "has something changed", then you can hook into the instance instead of all the fields.
What platform? The post makes me think .NET.
What is the underlying objects? For example, BindingList<T> as a source allows you to disable notifications by setting RaiseListChangedEvents to false while doing the update.
Other than that (or similar); yes, disconnect the binding during big updates
The easiest route to take is to use the BindingSource component for your data binding. Instead of binding your controls to a particular object (or IList), use that object as the DataSource for the BindingSource, then bind the controls to the BindingSource.
The BindingSource class has SuspendBinding() and ResumeBinding() functions.