Why does Silverlight Add Service Ref. use eventing instead of IAsyncResult? - silverlight

Ye Olde Add Web Reference generates XXXAsync calls to services that use eventing to inform the caller that the call had completed.
Add Service Reference in something like a WPF or console app, when told to generate async operations, uses the IAsyncResult design pattern (BeginXXX and EndXXX operations). My understanding is that this was generally regarded as a step forward in usability and flexibility - you can use a callback, you can begin blocking at any point in time simply by calling EndXXX, you can group wait handles and block on a set of operations, you can poll, etc.
Why doesn't ASR in Silverlight use IAsyncResult? My guess is because the designers wanted to make it very clear that full asynchronicity is in fact required, and if they had used the IAsyncResult design pattern, it would have been too easy to try just call Begin immediately followed by End, which would have made for a stumbling block that would have been hit by roughly 100% of new devs or people who didn't have a good grasp of async.

The Silverlight team provided immediate access to the event based async pattern because it's an easier to use approach (but a lot less flexible). For example, the event is fired in the display thread, allowing developpers unwilling to think about their thread model to forget about it.
If you need better flexibility (as me), the Begin/End async pattern is available for Silverlight too. In fact the event based generated code is based upon the IAsyncResult one.
Your generated Channel interface defines the begin/end methods, and you can use the channel factory to obtain an usable implementation of the interface.

From MSDN:
Usually, the event-based asynchronous model described previously raises the completion event on the same thread on which the service was called. This is convenient in many applications, because you often invoke services from the UI (User Interface) thread, and can update UI components (such as text boxes in our example) directly in the completion event handler.
Occasionally, you may want the completion event to be processed on a background thread. Either for this or for other reasons, you may want to use an alternative asynchronous invocation model based on the IAsyncResult mechanism and on Begin/End methods.
To use this model, you must first cast the proxy to an appropriate interface type. The interface type is generated automatically alongside the proxy by the Add Service Reference tool. You can then invoke the appropriate Begin method.
CopyIAsyncResult iar = ((CustomerService)proxy).BeginGetUser(userId, GetUserCallback, proxy);
Thanks to Kimberly for the MSDN link.

Related

Sharing data to client whenever API has results available?

I have the following scenario, can anyone guide what's the best approach:
Front End —> Rest API —> SOAP API (Legacy applications)
The Legacy applications behave unpredictably; sometimes it's very slow, sometimes fast.
The following is what needs to be achieved:
- As and when data is available to Rest API, the results should be made available to the client
- Whatever info is available, show the intermediate results.
Can anyone share insights in how to design this system?
you have several options to do that
polling from the UI - will require some changes to the API, the initial call will return a url where results will be available and the UI will check that out everytime
websockets - will require changing the api
server-sent events - essentially keeping the http connection open and pushing new results as they are available - sounds the closest to what you want
You want some sort of event-based API that the API consumers can subscribe to.
Event-driven architectures come in many forms - from event notification ('hey, I have new data, come and get it') to message/payload delivery; full-on publish/subscribe solutions to that allow consumers to subscribe to one or more "topics", with event back-up and replay functionality to relatively basic ones.
If you don't want a full-on eventing platform, you could look at WebHooks.
A great way to get started will be to start familiarizing yourself with some event-based architecture patterns. That last link is for Chris Richardson's website, he's got a lot of great info on such architectures and would be well worth a look.
In terms of the defining the event API, if you're familiar with OpenAPI, there's AsyncAPI which is the async equivalent.
In terms of solutions, there's a few well known platforms, including open source ones. The big cloud providers (Azure, GCP and AWS) will also have async / event based services you can use.
For more background there's this Wikipedia page (which I have not read - so can't speak for it's quality but it does look detailed).
Update: Webhooks
Webhooks are a bit like an ice-berg, there's more to them than might appear at first glance. A full-on eventing solution will have a very steep learning curve but will solve problems that you'll otherwise have to address separately (write your own code, etc). Two big areas to think about:
Consumer management. How will you onboard new consumers? Is it a small handful of internal systems / URLs that you can manage through some basic config, manually? Or is it external facing for public third parties? If it's the latter, will you need to provide auto-provisioning through a secure developer portal or get them to email/submit details for manual set-up at your end?
Error handling & missed events. Let's say you have an event, you call the subscribing webhook - but there's no response (or an error). What do you do? Do you retry? If so, how often, for how long? Once the consumer is back up what do you do - did you save the old events to replay? How many events? How do you track who has received what?
Polling
#Arnon is right to mention polling as an approach but I'd only do it if you have no other choice, or, if you have a very small number of internal system doing the polling, i.e - incurs low load, and you control both "ends" of the polling; in such a scenario its a valid approach.
But if its for an external API you'll need to implement throttling to protect your systems, as you'll have limited control over who's calling you and how much. Caching will be another obvious topic to explore in a polling approach.

Generic timer that works in both WinForms and other apps

I need to write a library class that performs timing operations, and raises a tick event periodically. I need this library to be usable from both WinForms and non-WinForms applications.
The problem is that the threading model is quite different for different types of applications. WinForms apps even have their own dedicated timers, but I don;t know in advance what type of app will be calling me.
Is there an established pattern for safely raising a timer event without prior knowledge of the type of app (WinForms, WPF, Silverlight, ASP.NET, etc.) that will use it?
Is there an established pattern for safely raising a timer event without prior knowledge of the type of app (WinForms, WPF, Silverlight, ASP.NET, etc.) that will use it?
There are timers that are platform neutral in the framework: System.Threading.Timer and System.Timers.Timer. However, these will both require you to handle the marshaling back to your synchronization context, as they raise their events on a threadpool thread.
You could provide this marshaling in a generic way - ie: make a "timer" class that wraps one of the above, taking a SynchronizationContext as an argument. When the timer's Tick event occurs, you could Post the data back to the context. This is, effectively, what the Windows Forms timer does.
You'd then just create it in your UI thread and pass SynchronizationContext.Current to the "new timer" class. This would work for Windows Forms, WCF, WPF, Silverlight, etc - as they all setup a SynchronizationContext on their "main" thread.

Approach to loading forms and busy indicator

I am "slowly" moving into Silverlight from asp.net and have a question about how to deal with situation where some code needs to be executed after web service calls have completed. For example, when user clicks on the row in the data grid a dialog box is shown that allows editing of the record. It contains numerous combo boxes, check boxes etc. So I need to first load data for each of the combo boxes, and than when all finished loading, I need to set the bound entity. Since I am new to this async thing, I was thinking to have some kind of counter that will keep track on how many calls have been dispatched, and as they finish reduce them by one, until it is zero, at which point I could raise an event that load has finished, and I could proceed with what ever is dependent on this. But this seems very clunky way of doing it. I am sure many have faced this issue, so how do you do this. If it helps, we use Prism with MVVM approach and Ria Services with Dtos.
What you've described is pretty much the way to go. There may be more elegant things you can do with locks and mutexes, but your counter will work. It has the bonus that you can see how many operations are still "in progress" at any one time.
You could dispatch your events sequentially but that would defeat the whole purpose of asynchronous operations.
If you analysed what each part of your UI needs you might be able to do some operations before all of your async events have finished. Making sure you start the longest running operations first might help - but there's no guarantee that the other shorter operations will finish first. It all depends on what resources are available on both the client and server at the time the call is made.

Duplex Callbacks or Client-Side Threading for Responsive WCF Clients

I have a certain service where specific functions will take longer to call than others, sometimes they might take seconds to return. In order to prevent the client's UI being blocked when this happens what is the preferred solution:
Use a Duplex channel and simply use the callbacks to update the UI when data is received.
Use a separate thread to call the service, and simply use request-reply operations, and then update the ui thread when data is returned.
Which solution is better, particularly when interoperability is favored but not strictly necessary, and in your opinion, which one is faster (and cleaner) to implement and maintain?
If you implement callback contracts then you are removing the need for the client to implement multithreading code. This might not be a significant advantage when working with .Net clients (as VS will auto generate the asynch proxy code for you), though could prove beneficial when working with clients of other platforms/languages.
Which one is cleaner? Well, that depends whether you are a client or server developer. If, as I suspect in your case, you are both, and you can just use .Net for client and server, then I'd probably be tempted to avoid callbacks for now. If you'd have implied that the service calls where taking 45 seconds then I'd say call back contracts, it really is subjective, but if I were to stick my neck out then I'd say that if responses take longer than 5 seconds then it is time to move to callbacks.
You should implement a CallBackcontract.
Here is an example.

Is WPF Dispatcher the solution of multi threading problems?

I have a very bad feeling about using lock in my code but now the Dispatcher of WindowBase exists and I want to use it everywhere.
For example I use a multi thread singleton WCF service who publish events on the EventAggregator of PRISM, the payload is immutable (it is just data) and every thread with a dispatcher can retrieve the event gracefully, whitout deadlock in their own dispatcher. (Not only UI thread, but also threads with database calls, threads with services call, threads which log or other threads with slow calls, because I don't want to freeze the UI).
But my problem is that this Dispatcher is coupled with WPF so I feel a bit guilty when I use it everywhere, I feel that the dispatcher was not created for my use case in mind.
Does it exist another Dispatcher implementation not coupled with WPF ? or that's OK to abuse it ?
Thanks,
Update
The solution that Paul Stovell give to me is to create an interface IDispatcher, and an adapter for the Wpf Dispatcher, so this will be easier to test !
This solution was good for me because, I refactored my tests and I can now use a SynchronousDispatcherAdapter in my tests (Thanks to it, I don't have to use the Dispatcher of WPF in my tests).
Using the Dispatcher instead of a BackgroundWorker make sense, because I'm using a multi publisher / subscriber pattern (with PRISM), and thanks to the Dispatcher every event handler are called on threads who subscribe them to the event. This means that the only point where multi threading issue can happen is at the payload of my event (I made him immutable).
My different threads don't communicate directly between them they can just publish and subscribe to event.
Thus, database calls, logs calls, services calls, UI calls run on different threads and don't know about each other (they only know about events they subscribe and publish).
The background worker will make sense, when I will make some calls from my UI to a repository.
But I hope to find a design without using BackgroundWorker because I prefere to use this subscriber/publisher pattern (I think it makes my code more readable)
The main issue with using the Dispatcher (or BackgroundWorker) is that it's difficult to test, unless your testing harness actually has a UI thread.
Solution 1
Use the SynchronizationContext. It provides the same ability to invoke on the UI thread and works in Windows or WPF. Testing it also possible.
Solution 2
Think of the dispatcher as being just another service. As you use PRISM, you are familiar with services and IOC. Here is how such a service may be used:
// Not a UI component
public class MyDomainService : IMyDomainService
{
private readonly IDispatcher _dispatcher;
public MyDomainService(IDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
private void GotResultFromBackgroundThread()
{
_dispatcher.Dispatch(() => DoStuffOnForegroundThread());
}
}
This allows you to substitute in different implementations for your platform/testing.
Here is an example of IDispatcher, a WPF implementation and a test implementation. You would register them with your IOC container just like any other service, and they are available to both UI and other services.
yes and no.. its a rendering thing..not a threading thing per se..
The Dispatcher selects work items on a priority basis and runs each one to completion. Every UI thread must have at least one Dispatcher, and each Dispatcher can execute work items in exactly one thread. as per this this link from Microsoft.
You still have to handle on your own any threads you start yourself.
Check this one for info on: Multithreaded Programming with the Event-based Asynchronous Pattern
Personally I use the Background Worker for my threading needs.
Best Practices here.
I'm going to necro the heck out of this, but this sounds like a bad idea. What you are saying is that you need a queue for your publisher to dump items on for its subscribers. A Dispatcher, at its core, is just a glorified queue, with a LOT of overhead around it. The overhead is specifically for protecting access to UI resources, which you aren't using. That suggests it's the wrong thing to use.
The person who suggested a SynchronizationContext is on a good path. This accomplishes what you want (safely marshalling data to another thread), without tying you to a UI concept. You could write an extension method which marshals your event to the SynchronizationContext requested by each subscriber of the event (it is available by casting the Target of your subscribing Delegate to ISynchronizeInvoke. The result of that cast will allow you to know if it needs to be marhalled, and can do it automatically for you.
Even better would be to just use a queue with appropriate locking semantics. The overhead of the lock is unlikely to be an issue, and if it is, your use of the Dispatcher would be far more destructive than a simple lock. In this case, simpler is better. They key would be to only keep the lock to add/remove an item from the queue. Your subscribers should perform whatever work they do outside of the lock.

Resources