Now I know about the Dispatcher and the DispatcherTimer and their benefits.
But I've always been under the impression that an async web-service/WCF callback (completed event handler) are automatically handled by the UI thread.
But looking at some references online such as the one linked below, it seems this is NOT the case.
So the strange thing is that i haven't been using the Dispatcher to update the UI (updating data-bound ObservableCollections) within service completed events, yet I've never received a cross-thread exceptions.
Can anybody explain why i havent seen this exception, or confirm if my original assumption is correct?
Reference:
http://www.silverlightshow.net/items/Tip-Asynchronous-Silverlight-Execute-on-the-UI-thread.aspx
What the dispatcher do is putting a message into the normal windows message queuse. If you update an element bound to an UI element you don't need to use a dispatcher because the PropertyChanged raised when you update your model already put a message into the windows message queue, so you don't need to call any dispatcher, otherwise you just do two round trips into the window message queue.
The easiest explanation is it depends on how you are retrieving your data and whether you are trying to update the UI. For instance, when using HttpWebRequest directly it will always need to be marshaled back to the UI thread. However if you are using WebClient then that is done for you. WCF will also do some marshaling for you.
"WCF proxies in Silverlight applications use the SynchronizationContext of the thread from which the web service call is initiated to schedule the invocation of the async event handler when the response is received."
http://tomasz.janczuk.org/2009/08/improving-performance-of-concurrent-wcf.html
In other words, WCF will marshal the call back to the thread in which it was called from. So if you are invoking your service calls from the UI thread, then they will come back on the UI thread. If you are invoking your services on a different thread then you will need to do the marshaling yourself.
Hope that helps.
Related
I want to call some function repeatly in client's browser.
System::Timers::Timer work only on serverside how i know...
In Silverlight you can use System::Threading::Timer or System::Windows::Threading::DispatcherTimer. If your timer callback is mainly interacting with the UI, use the DispatcherTimer, otherwise use the regular Timer.
I implemented the observer design pattern in my application, but my app sends to an remote server requests via http protocol that take some time to resolve.
So, naturally, I did the sending an receiving part in a separate thread.
Can you please tell me how to make an window that observes the RequestObject to modify it's state based on the state of the request?
In the debugger step by step mode the window runes the code that I want it to do, but the window never refreshes its self.
Since I don't have a sample of your code I don't know the exacts of how you are updating your UI. If you are attempting to update the UI in the seperate thread that could be your issue. This may be of some help. http://msdn.microsoft.com/en-us/magazine/cc188732.aspx
You may also consider using the Task Parellel Library to perform your asyc operations.
http://msdn.microsoft.com/en-us/library/dd997423.aspx
Anyone found a good way to make asynchronous calls to the db via entity framework? Use background worker thread? This is a WPF application.
I know in RIA services there is a loadcompleted event that does not seem to exist in entity framework's object context.
Thanks!
I've written a blog post about async calls via commanding in a WPF application
http://devblog.terminto.com/2010/11/03/threading-as-command-in-mvvm/
At work I use the same technique and do calls to DB (EF4).
Is this useful, or are you asking about more entity framework-specific async methods?
I have a pretty simple scenario:
I have an asynchronous WCF service calls in my silverlight app.
I want to execute those on a separate thread ( or similar) because they freeze up my UI.
All service calls are meant to update the ViewModel thus the/ a UI control on the page, so need to find a way to do that from the thread running the service calls without getting the familiar cross thread exception.
Any suggestions?
Many thanks.
In talking with folks on the WCF team, this is my understanding about how it works. If you simply make the call from a background thread, it won't work, as the WCF subsystem will marshal the call back onto the thread from which you initially opened the connection (normally, the UI thread). So what you have to do is create a worker thread, and then explicitly open the connection from that thread. Then, whenever you make a call, it will get marshaled back onto that thread. And of course, once you've received your callback and done your processing (on the background thread), then make sure that you marshal any UI changes back onto the UI thread using Dispatcher.BeginInvoke().
Dispatcher.BeginInvoke is the best solution.
Partial defination of service proxy:
public void GetItemById(int id, Action<ItemModel> callback)
{
AsyncCallback onCompleted = ar =>
Deployment.Current.Dispatcher.BeginInvoke(() =>
callback(this.Channel.EndGetItemById(ar)));
this.Channel.BeginGetItemById(id, onCompleted, null);
}
Call from MVVM:
var proxy = new MyServiceProxy();
proxy.GetItemById(5, item => this.Item = item);
You can either use a BackgroundWorker, or make your client proxy support the Asynchronous Pattern.
Make sure you dispatch UI updates to the proper thread as described here:
http://russelleast.wordpress.com/2010/02/27/using-wcf-async-pattern-with-silverlight-3/
I have a wpf composite application with 3 or 4 modules that will always be loaded. In my shell I have a toolbar with buttons to active corresponding views from these modules. I injected an IEventAggregator into the shell presentor so that when a button is pressed I can publish an event that the corresponding module controller has subscribed to. When the event is caught the controllor will active its view.
Thats the theory anyways, in practice my controller is not catching the event. There are no errors in publishing or subscribing. I thought at first that there might be an issue with the eventAggregator not being the same, but thats not the case, and the event has a subscriber when its published.
Can anyone think of a reason why the event is not getting caught?
(Or any suggestions on a different way to get my view to show would be helpful too!)
Do you have your module controller 'alive'? Are you subscribing to the event using weak delegate reference or strong reference?
Seems that what is happening is that your module controller is being disposed, and so, the event is not getting caught.
To subscribe with a strong reference, use the keepSubscriberReferenceAlive option on the Subscribe method.
You can check the Event Aggregator article from the documentation which might provide more insight.
If that still does not works, can you share your repro code with me so I can take a look to it? (ezequieljadib at hotmail dot com)
Thanks,
Ezequiel Jadib