We have an application that is essentially implementing its own messaging queue. When a user interacts with the application it will generate an action, being a custom action and not the .NET class, that will be handled by our ActionDispatcher.
In the ActionDispatcher class I have a Stack of CustomAction objects. I'd like to run the ActionDispatcher in its own thread, but then you have all the issues with communicating with the main UI thread using Invoke and BeginInvoke.
There are several different methods that the ActionDispatcher may call, each one would require a delegate on the UI side to be used to communicate with the other thread I believe. Is there a simplier way?
The reason for wanting a seperate thread is that the ActionDispatcher processes messages that originate from a server as well as the UI. This is a client application, and many actions are generated by the server. The idea is that I have we have our own queue that both the UI and server add messages to.
It really depends on the architecture of your application, but the quick and short answer is: No. If you're not on the UI thread, then you have to use the Dispather's Invoke or BeginInvoke method to get access or execute code back on the UI thread.
As a side note, this is a little different than in WinForms, it almost sounds like you're coming from a WinForms perspective, so you might want to look up the WPF Dispatcher.
On the other hand, I would suggest that you look into something like Prism's IEventAggregator. I'm sure there are other similar implementations, but Prism has one nice feature, you can tell it you want to subscribe to an event and have it come in on the UI thread and prism does the rest of the work for you.
Personally, I think using an EventAggregator pattern is better, I'm not sure it's necessarily simpler though.
You need to use Dispatcher.CheckAccess().
http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.checkaccess.aspx
Related
Quick question
If I have a WebWorker that has a function that returns an Observable<Any> back to the UI code, if I then subscribe to the Observable, is the observable running on the UI thread or the WebWorker thread?
I ask this question because I am writing an Angular2 app with RxJS, and to improve performance I want some of the hard-working Observables to run within WebWorkers, passing a stream of results over to the UI thread
I assume your web worker is sending an observable back to your main thread via a message.
Messages are intended to be used both ways, you can't send objects that expose functionality.
The solution is to have your webworker post messages, and then have a main-thread service handle those messages and pipe them into a Subject, which it exposes to your application as an IObservable.
Keep on mind that web worker messaging doesn't support channels, so you'll need to apply your own discriminator if you use messages on multiple areas of your app.
The short answer is that Rx doesn't introduce concurrency unless you instruct it to via SubscribeOn, ObserveOn or some transform operator like Buffer.
So any code in the "Subscribe" part of the Rx operator will run in the same thread you called .Subscribe(onNext etc). However the actual callbacks onNext, onError and onComplete will run on whatever thread the observer uses, you don't control this (unless you wrote the operator).
To ensure you receive calls on the UI thread you should add a .ObserveOn(UIDispatcherThread). This will guarantee the thread you are called back on and make it testable.
Hope that helps.
As others noted, communication between calling code and webworkers is serialized and so you cant send something that has behavior (such an observable) over the wire.
I've written a little helper that uses Rxjs to help resolve this and other pains of developing with webworkers. Read about it here, github repo here
What I'm trying to attempt is to access methods on a Silverlight control via the COM automation model. Theoretically it should be possible, as exposing the Silverlight control's methods as scriptable members exposes them through an IDispatch interface. I have been able to access the IDispatch interface through the automation model correctly but when I attempt to call a method on the exposed interface via Invoke it crashes.
I was wondering if anyone knew whether this was expected behaviour, i.e. I'm violating some basic sandboxing requirement, or whether this should work and it is just something in my implementation that needs correcting? Cheers.
There is an alternate hosting model available, details on MSDN: http://msdn.microsoft.com/en-us/library/dd550717(v=VS.95).aspx
It is very involved to use these methods, but you might just need to do that.
Here's the Silverlight agcore COM reference: http://msdn.microsoft.com/en-us/library/cc296246(v=VS.95).aspx
To answer my question, yes this is possible and exactly as per my question's description. The caveat turned out to be that Silverlight doesn't provide an event corresponding to when a call to the IDispatch interface will succeed, e.g. when it's initialized "enough" to correctly respond.
Upon stopping my attempts on load events (e.g. OnLoad, OnPageComplete, etc) and making it a manual step off a button or similar I could successfully access the IDispatch interface.
I'm building a single window WPF application
In the window is a list items (which are persisted in a database of course)
Periodically I need to start a background task that updates the database from an Atom feed. As each new item is added to the database, the list in the UI must also update to reflect this. I don't want this background task to slow down the UI but at the same time it needs to interact with the UI.
Having read loads of articles and seen lots of simple examples, I am still unsure of the best way to implement this.
What I think maybe I could do is:
On the Window_Loaded event, create a DispatchTimer.
When the Tick event fires, call UpdateDb() method.
UpdateDB() will get the items from the Atom feed and add to the database. As I iterate through each item I will call another method to rebind the list to the database so that it "refreshes".
When all the tasks are finished reset the DispatchTimer ??? (not sure if this can / needs to be / done).
Remember, this is background task so a user could be using the UI at the same time.
How does this sound?
Thanks.
This sounds suboptimal because you're doing database connectivity on the UI thread. When the Tick event fires on the DispatcherTimer, handlers will execute on the UI thread. You need to minimize the amount of work you do on this thread to keep the UI responsive, and you definitely shouldn't be doing IO-bound work on this thread.
I would probably have a data service whose responsibility is to update the database and raise events as changes are made. Your UI layer can attach to these events and marshal to the UI thread to apply changes. To marshal to the UI thread, you just need to call Dispatcher.Invoke.
Regardless of your specific approach, the key is to do as much as you can (including any database access) on a separate thread. Marshal back to the UI thread as late as possible and do as little work as possible on the UI thread.
One other thing to note is that WPF automatically marshals changes to scalar values for you. You only need to marshal changes to collections (adding/removing/replacing items).
Your approach would work.
You'd start the timer when the app loads. For each tick of the timer, you start a thread to update the database. Once the database update has happened, you can call .BeginInvoke() on your UI objects to update the UI on the presentation thread (that will be the only time your UI should be affected).
I'd use a System.Threading.Timer, which will call a specified method at a specified interval on a threadpool thread, so no need to create an additional thread, do your db work with that and marshal back to the ui thread as needed.
WPF Multithreading with BackgroundWorker by Pavan Podila:
The good news is that you really don’t have to write such a component since one is available already: the BackgroundWorker class introduced in .Net Framework 2.0. Programmers who are familiar with WinForms 2.0 may have already used this component. But BackgroundWorker works equally well with WPF because it is completely agnostic to the threading model.
I am writing an app that listens on a network connection, and when some data arrive, it replies back, and depending on incoming data, it may need to ask user (show dialog) before replying back.
I don't know how to do this cleanly in M-V-VM architecture: the events and binding to observable collections are nice if I need to just update GUI based on incoming data, but what if I actually need an anwer from user before replying back?
And to make things worse, I want to do it synchronously, because I want my reply algorithm to be at one place, not partitioned into multiple callbacks with unclear 'who-calls-who' responsibilities.
Simply, something like
HandleMessage(Message msg){
string reply;
if (msg.type == 1) {
reply = ...
} else {
string question = msg...
reply = ShowModalDialog(question); // MVVM violation!
}
sender.Send(reply);
}
but I don't want to call view or viewmodel from model, as model needs to be reusable and testable - I don't want popping dialogs in every test run, and it would be violation of MVVM! No events (they are just one-way as far as i know, and have no backwards channel to get reply to event origin) or databinding, as it would be asynchronous.
Is this doable? This is a question I asked several test driven development propagators, and so far, I didn't get practically usable answer. Yet, a need for some additional input in the middle of processing is fairly common.
Thanks!
EDIT: this is application logic, so it clearly belongs to model, and even if in this case it didn't, I'd like to know the solution for cases when I really need user's input in the middle of business logic routine in model.
This is one of those problems that MVVM doesn't solve on it's own. One solution would be to use a service to query the user and then have the ViewModel use that service.
In my project we're using PRISM which besides providing a services framework also provides other tools for making GUI development easier.
Here's a writeup of how services work in PRISM.
So specifically in your case I would create some sort of IOC, register a query service with it, then in the ViewModel pass in the IOC and then use the IOC to get the query service, and use that to query the user. More work? Sure. But it means you can replace the query service with another implementation for testing by simply replacing it in the IOC.
MVVM + Services = Ultimate Power!
I don't know if this idea is in strict keeping with the tenets of MVVM, but...I would encapsulate the dialog functionality as a service (referenced via an interface). The implementation of the service would be in the UI layer, but for testing purposes you would just "mock" the interface.
Actually, it doesn't ALL belong in the application logic.
It seems like you have 2 different "views". There is the initial one (data coming in over the net), and a second one (confirmation dialog).
The model needs to determine that a new view needs to be displayed, signal the view to display it, then later respond to the input from that view.
Don't try to do it all in one step.
I had to design and implement my own publish subscribe eventing to satisfy the requirements of a dynamic UI Winform design. Is there any .Net library that supports pub/sub out there that I can compare mine and improve?
Why not start with this list-based publish/subscribe pattern (using WCF) on MSDN?
Actually I went further than that. For example you can create a SystemEvent and publish it on a subject with a name of 'Application.UI.TreeInstance.[InstanceName].Node.Clicked' and if you register for anything like 'Application.' or 'Aplication.UI.' or 'Application.UI.TreeInstance.[InstanceName].Node.*' or the full subject you will get called on your delegate through multicast and receive the event. The SystemEvent you can define as you want; it has a ValueNamePairCollection and a public interface to get the data out as you feel like. You can register for synchonous and asynchronous processing and offcourse Unregister as well. My UI elements now process events that they care without having to know who publishes them.
If the community has any interest in stuff like this I could package up the code and make it available so we can all share and improve. I have tested it thoroully and works 100%.Also I wrote some monitoring GUI that you can see in real time what is happening with publications and subscriptions as well as registrations and unregistrations.