In an MvvmCross solution I have a singleton Service class which gets items from a web service and updates a public ObservableCollection. It does this every five seconds and items may be added or removed or their properties changed.
I also have a ViewModel which has a public property which is set to the Service's ObservableCollection. The View is bound to the ObservableCollection so that when items are added, removed or changed the view should update to show this.
However, as expected, I am getting a threading exception because the ObservableCollection is being updated by a thread other than the Main/UI one and the binding therefore cannot update the UI.
Within the Service I do not have the InvokeOnMainThread call readily available so there is no obvious cross platform way to get back on to the main thread when updating the ObservableCollection. Also, doing this just seems wrong - a Service shouldn't be concerning itself with UI matters (whereas a ViewModel can).
Also I am a bit nervous about exposing events from a Service in case this causes ViewModels to not be Garbage Collected. I note that in #slodge's N+1 series http://mvvmcross.wordpress.com/ he is using a messenging service presumably to avoid just this.
So a possible solution may be to publish a message with the latest list of items, and for the ViewModel to subscribe to the message and update its own ObservableCollection on the UI thread by comparing the message contents to it. But this seems a little clunky.
Any suggestions on the best way to implement this would be appreciated - thanks.
The original requirement that INotifyCollectionChanged must be called on the UI thread really comes from the synchronous way that the Windows controls update based upon the Added/Removed/Moved/Replaced/Reset notifications.
This synchronous update is, of course, entirely sensible - it would be very hard to update the UI display while another thread is actively changing it.
There are 'new' changes in .Net 4.5 which may mean the future is nicer... but overall these look quite complicated to me - see https://stackoverflow.com/a/14602121/373321
The ways I know of to handle this are essentially the same as those outlined in your post:
A. keep the ObservableCollection in the Service/Model layer and marshal all events there onto the UI thread - this is possible using any class which inherits from MvxMainThreadDispatchingObject - or can be done by calling MvxMainThreadDispatcher.Instance.RequestMainThreadAction(action)
Whilst it's unfortunate that this means your Service/Model does have some threading knowledge, this approach can work well for the overall App experience.
B. make a duplicate copy of the collection in the ViewModel - updating it by some weak reference type mechanism
e.g. by sending it Messages which tell it what has been Added, Removed, Replaced or Moved (or completely Reset) - note that for this to work, then it's important that the Messages arrive in the correct order!
or e.g. allowing snapshots to be sent across from the Service/Model layer
Which of these to choose depends on:
the frequency, type and size of the collection changes - e.g. whether you are only getting occasional single line updates, whether you are getting frequent large bursts of changes, or whether you are mainly seeing complex groups of changes (which essentially are Resets as far as the UI is concerned)
the animation level required in the UI - e.g. should added/deleted items animate in/out? If no animation is required then it can sometimes be easier just to replace the entire list with a new snapshot rather than to work out the incremental changes.
the size of the collection itself - obviously duplicating a large collection can cause out-of-memory issues
the persistence required on the collection - if persistence is required, then ObservableCollection itself may not be appropriate and you may need to use a custom INotifyCollectionChanged implementation (like the MyCustomList samples)
I personally generally choose the (A) approach in apps - but it does depend on the situation and on the characteristics of the collection and its changes.
Note that while this is most definitely an mvvm issue, the underlying problem is one independent of databinding - how do you update an on-screen display of a list while the list itself is changing on a background thread?
Related
The Bloc manual describes the example of a simple Todos app. It works as an example, but I get stuck when trying to make it into a more realistic app. Clearly, a more realistic Todos app needs to keep working when the user temporarily loses network connection, and also needs to occasionally check the server for updates that the user might have added from another device.
So as a basic data model I have:
dataFromServer, which is refreshed every five minutes, and
localData, that describes what changes have been made locally but haven't been synchronized to the server yet.
My current idea is to have three kinds of events:
on<GetTodosFromServer>() which runs every few minutes to check the server for updates and only changes the dataFromServer,
on<TodoAdded>() (and its friends TodoDeleted, TodoChecked, and so on) which get triggered when the user changes the data, and only change the localData, and
on<SyncTodoToServer>() which runs whenever the user changes the todo list, or when network connectivity is restored, and tries to send the changes to the server, retrieves the new value from the server, and then sets the new dataFromServer and localData.
So obviously there's a lot of interaction between these three methods. When a new todo is added after the synchronization to the server starts, but before synchronization is finished, it needs to stay in the local changes object. When GetTodosFromServer and SyncTodoToServer both return server data, they need to find out who has the latest data and keep that. And so on.
Coming from a Redux background, I'm used to having two reducers (one for local data, one for server data) that would only respond to simple actions. E.g. an action { "type": "TodoSuccessfullySyncedToServer", uploadedData: [...], serverResponse: [...] } would be straightforward to parse for both the localData and the dataFromServer reducer. The reducer doesn't contain any of the business logic, it receives actions one by one and all you need to think about inside the reducer is the state before the action, the action itself, and the state after the action. Anything you rely on to handle the action will be in the action itself, not in the context. So different pieces of code that generate those actions can just fire these actions without thinking, knowing that the reducer will handle them correctly.
Bloc on the other hand seems to mix business logic and updating the state. API calls are made within the event handlers, which will emit a value possibly many seconds later. So every time you return from an asynchronous call in an event handler, you need to think about how the state might have changed while that call was happening and the consequences this has on what you're currently doing. Also, an object in the state can be updated by different events that need to coordinate among themselves how to avoid conflicts while doing so.
Is there a best practice on how to avoid the complexity that brings? Is it best practice to split large events into "StartSyncToServer" and "SuccessfullySyncedToServer" events where the second behaves a lot like a Redux reducer? I don't see any of that in the examples, so is there another way this complexity is typically avoided in Bloc? Or is Bloc entirely unopinionated on these things?
I'm not looking for personal opinions here, only if there's something I missed in the Bloc manual (or other authoritative source) about how this was intended to work.
The other day, in a code review, I saw some questions about the safety of setting a property from a worker thread. A coworker made the comment, "This property is bound to the UI, and data binding is thread-safe."
I've been using XF for a while, but always assumed this wasn't true: that if I wanted to update ViewModel properties bound to the UI I'd have to make those changes on the UI thread. I just spent a few minutes poking around the documentation, and I don't see an obvious answer other than that directly manipulating BindableProperties has thread affinity. It also matters to me if that's a blocking UI thread execution or not.
I could make a project to test it out myself, but these kind of issues always seem to be intermittent so I'd like to know I'm just missing the right documentation.
(It's relevant to investigating a crash we're seeing that happen within mainly Xamarin call stacks. We raise an event from a worker thread, a VM handles that event and updates some properties. If that's being scheduled for the UI thread, there could be some interleaving issues we didn't prepare for and I'm that much closer to addressing the crash. If it's not being scheduled for the UI thread... I'm surprised it's worked this long.)
I've been using XF for a while, but always assumed this wasn't true: that if I wanted to update ViewModel properties bound to the UI I'd have to make those changes on the UI thread.
You're right. 100% right. You can use Device.InvokeOnMainThread() for this.
To be complete, there is one case where it doesn't matter: PropertyChanged
https://github.com/xamarin/Xamarin.Forms/blob/b645064/Xamarin.Forms.Core/BindingExpression.cs#L542
In that case, the Binding is applied on the main (UI) thread.
Assumptions
We interact with the UI exclusively via binding. So only setters and getters are playing.
Getters
The code referred to in github by #Stephane, only means, that your bound getter(s) will be called in the UI thread. No more no less.
Btw, I would not rely on the source code (I mean: implementation), instead the specification what matters. Implementation can change anytime, and if the specification does not requires this, then unit tests will not check this, so there will be a big surprise...
Setters
However it is still not clear, if can you call your setter(s) in a background thread. Regardless the answer is yes or no, it implies further tasks to solve.
a) If you can call setters in any thread: This means, that your viewmodel internal data is exposed to race conditions, because will be called from the UI thread, and you will access them in a background thread. Conclusion: You must guard the data with the usual concurrency patterns, or use thread safe classes, plus: your getter and setter must be atomic.
b) If it turns out you can not call setters in any thread: Then you must use Device.InvokeOnMainThread(). But this is only the half of the story. In methods of your background thread, you are modifying say a List instance. This will be accessed in the UI thread by the getter, and you are modifying it in a background thread concurrently when you say populate it. Theoretically it is possible the user interacts with the UI during the population period, what let the binding evaluated, getter is called.
Conclusions:
If there are multiple threads accessing to the very same data, you must always lock you data.
Regardless what the current source code implies the safest way to marshall the getter and setter to the UI thread. This will not cause significant overhead: If the executions is already in the UI thread, marshall will do nothing.
Note: Even you marshall both you getters and setter to the UI thread, you will access the data in background threads so guard against race conditions or using thread safe classes are essential.
I'm a beginner to the flux model but I think I understand it at a high level:
event creator -> events -> dispatch -> store -> view and around we go!
Given that the flux model supports multiple stores, if you have say an event loop that dispatches to 2+ stores, that in turn updates the same view.
How do you manage any inadvertent flicker that would come from that process?
I haven't quite enabled/used react yet (I assume a catch all answer will be that react handles this heavy lifting part of reducing this) but conceptually how could this work outside a specific implementation.
Since store changes are applied serially across stores, do you just wait until all the stores are down processing the dispatcher, and then allow them individually to fire all their changes? Even then you still would loop through and dispatch events at the end, and you'd still potentially have overlapping updates to the UI.
Thanks!
You have different options here:
The vanilla solution is to utilize a waitFor() function in your store-structure, and ensure that in the end each component has only one store it listens to. More or less like this:
Caveat is that your action types and store structures need to be in sync: Each action needs to communicate to all stores that are included in a waitFor cycle. The example in the picture will fail to trigger a render. The top-most store is not listening to the action from dispatcher, and the right store will keep waiting for update. Also, the red line may cause a similar dead end, if it is only 1 of the components. My way of dealing with this is: make all stores in the first line listen to ALL actions, and if the action is irrelevant: emit change.
The other option is to consolidate your data into a single store.
This does not make the issue go away: you need to handle the dependency issues inside the single store. But it does take away the hassle of many actions, many waitFors, and many change emissions..
Remember that the action is processed synchronously - all stores will have emitted, the controller views with have called setState, etc. before the stack unwinds and browser gets a chance to re-render the DOM, so flicker is not possible (the browser won't render in the middle of a function running, since otherwise all DOM manipulation code would cause random flickering).
However, as you say, there will potentially be multiple stores emitting changes, and multiple components listen to them, and hence you may end up calling 'setState' multiple times (even on the same component). This sounds inefficient, but under most circumstances it isn't. As long as the current action originated from an event that came from React (e.g. an event handler added to a component in the JSX), React automatically batches all calls to setState and only does the re-render to the DOM (i.e. any required DOM updates) once, immediately (and synchronously) after you have finished processing the event.
There is a case to be aware of - if you dispatch an action from something outside of a React event handler (e.g. a promise.then, an AJAX callback, setTimeout callback, etc.) then React will have to re-render for every single call to setState in that function, since it doesn't know when else to do it. You can avoid this by using the undocumented batched rendering feature (0.14, note that 0.13 had a different API for this):
ReactDOM.unstable_batchedUpdates(myFunctionThatDispatchesActions);
An alternative might be to use an off-the-shelf Flux implementation which does this for you already. See e.g. https://github.com/acdlite/redux-batched-updates
I am attempting to learn and apply the CQRS design approach (pattern and architecture) to a new project but seem to be missing a key piece.
My client application executes a query and retrieves a list of light-weight, read-only DTOs from the read model. The user selects an item and clicks a button to initiate some action. The action is performed by creating and sending the corresponding command object to the write model (where the command handler carries out the action, updates the data store, etc.) At some point, however, I need to update the UI to reflect changes to the state of the application resulting from the action.
How does the UI know when it is time to refresh the original list?
Additional Info
I have noticed that most articles/blogs discussing CQRS use MVC client apps in their examples. I am working on a Silverlight client right now and am beginning to wonder if the pattern simply doesn't work in that case.
Follow-Up Question
After thinking more about Bartlomiej's response and subsequent discussion, I am wondering about error handling in CQRS. Given that commands are basically fire-and-forget asynchronous operations, how do we report an error condition to the UI?
I see 'refreshing the UI' to take one of two forms:
The operation succeeds, data has changed and the UI should be updated to reflect these changes
The operation fails, data has not changed but the user should be notified of the failure and potential corrective actions.
Even with a Post-Redirect-Get pattern in an MVC, you can't really Redirect until you know the outcome of the operation. None of the examples I've seen thus far address these real-world concerns.
I've been struggling with similar issues for a WPF client. The re-query trigger for any data is dependent on the data your updating, commands tend to fall into categories:
The command is a true fire and forget method, it informs the back-end of a state change but this change does not need to be reflected in the UI, or the change simply isn't important to the UI.
The command will alter the result of a single query
The command will alter the result of multiple queries, usually (in my domain at least) in a cascading fashion, that is, changing the state of a single "high level" piece of data will likely affect many "low level" caches.
My first trigger is the page load, very few items are exempt from this as most pages must assume data has been updated since it was last visited. Though some systems may be able to escape with only updating financial and other critical data in this way.
For short commands I also update data when 'success' is returned from a command. Though this is mostly laziness as IMHO all CQRS commands should be fired asynchronously. It's still an option I couldn't live without but one you may have to if your implementation expects high latency between command and query.
One pattern I'm starting to make use of is the mediator (most MVVM frameworks come with one). When I fire a command, I also fire a message to the mediator specifying which command was launched. Each Cache (A view model property Retriever<T>) listens for commands which affect it and then updates appropriately. I try to minimise the number of messages while still minimising the number of caches that update unnecessary from a single message so I'll (hopefully) eventually end up with a shortlist of update reasons, with each 'reason' updating a list of caches.
Another approach is simple honesty, I find that by exposing graphically how the system updates itself makes users more willing to be patient with it. On firing a command show some UI indicating you're waiting for the successful response, on error you could offer to retry / show the error, on success you start the update of the relevant fields. Baring in mind that this command could have been fired from another terminal (of which you have no knowledge) so data will need to timeout eventually to avoid missing state changes invoked by other machines also.
Noting the irony that the only efficient method of updating cache's and values on a client is to un-separate the commands and queries again, be it through hardcoding or something like a hashmap.
My two cents.
I think MVVM actually fits into CQRS quite well. The ViewModel simply becomes an observable ReadModel.
1 - You initialize your ViewModel state via a query on the ReadModel.
2 - Changes on your ViewModel are automatically reflected on any Views that are bound to it.
3 - Certain changes on your ViewModel trigger a command to propegate to a message queue, an object responsible for sending those commands to the server takes those messages off the queue and sends them to the WriteModel.
4 - Clients should be well formed, meaning the ViewModel should have performed appropriate validation before it ever triggered the command. Once the command has been triggered, any event notifications can be published onto an event bus for the client to communicate changes to other ViewModels or components in the system interested in those changes. These events should carry the relevant information necessary. Typically, this means that other view models usually don't have to re-query the read model as a result of the change unless they are dependent on other data that needs to be retrieved.
5 - There is an object that connects to the message bus on the server for real-time push notifications when other clients make changes that this client is interested in knowing about, falling back to long-polling if necessary. It propagates those to the internal message bus that ties the components on the client together.
6 - The last part to handle is the fact that clients can be occasionally connected, which should be the only reason a command fails (they don't have internet access at the moment), which is when the client should be notified of problems.
In my ASP.NET MVC 3 I use 2 techniques depending on use case:
already well-known Post-Redirect-Get pattern which fits nicely with CQRS. Your MVC action that triggers the command returns a redirection to action that performs a query.
in some cases, like real-time updates of other clients, I rely on domain events/messages. I create an event handler that uses singlarR to push changes to all connected and interested clients.
There are two major ways you can take as far as I know :
1) design your UI , so that the user does not see its changes right away. Like for instance a message to tell him his action is a success, and offering him different choices to continue his work. this should buy you enough time to have updated your readmodel.
2) more complex, but you might keep the information you have send to the server and shows them in the interface.
The most important I guess, educate your user if you can so that they know why the data is not here... yet!
I am thinking about it only now, but these are for sync command handling, not async, in async things go really harder on the brain...the client interface becomes an event eater too..
Lets take this example. I have a AView which is bound to AViewModel. AView should execute an ACommand on AViewModel, and pass it a parameter. The problem is that ViewA doesnt have enough information to pass to command, so another BView needs to be displayed, in order to gather information from the user. After the VIewB is closed, ViewA invokes ACommand on AViewModel, and passes parameter to it.
How to handle this scenario? Should I allow AView to communicate directly to BView, or I am breaking some rule if I do so?
Another way I am thinking is to invoke a ACommand on AViewModel without a parameter, then from VIewModelA send a message that a information is required to complete the task. This information is captured by MainPageViewModel, than sends a request to open BView, which is bound to BViewModel. When BView is closed, a BVIewModel sends a message with additional info, and ViewModelA has subscribed to this type of message, so it receives it, and completes the task. Pretty complicated for just entering values in two text boxes, right? :)
There are 3 golden rules to MVVM: Separation, Separation & Separation :)
Reasons include: Automated testing of components, complete separation of functionality (e.g. for independent modules), independent team development of modules (without tripping over each other) and generally just easier to figure out what does what.
In answer to your interconnecting two Views: you are adding dependencies that should not exist. Separation of concerns is more important than a little complexity (and I would argue that the messaging model is less complex than maintaining a direct interconnection).
The complexity of publishing/listening for an extra message is nothing compared to the harm of interconnecting unrelated components so your last suggestion is "better", but I would actually suggest a cleaner approach to the whole problem:
A few guidelines:
Views should not know where their data comes from, only how to display a certain shape of data. Command execution is via bindings to ICommands on the VM.
ViewModels should hold a certain shape of data and commands. It should have no idea where the data comes from or what is binding to it.
Models hold the actual data, but have no idea where it is consumed.
Controllers (often overlooked in MVVM) register/push events, populate VMs from models, set the code in ICommands, control visibility of views etc. Controllers are the only thing actually required to stay in memory at all times and they are quite slim (mostly code & little data).
Basically I would suggest adding Controllers to your MVVM pattern (MVCVM?). App/modules create and initialize controllers. Controllers subscribe to events and provide the logic of the application.
Try this pattern and see how simple it becomes to work with lots of Views, ViewModels and Models. You do not mention what language or framework you are using, so I can't make specific suggestions for examples.