Design pattern for asynchronous calls in C# - c#

I'm designing a desktop application with multiple layers: the GUI layer (WinForms MVP) holds references to interfaces of adapter classes, and these adapters call BL classes that do the actual work.
Apart from executing requests from the GUI, the BL also fires some events that the GUI can subscribe to through the interfaces. For example, there's a CurrentTime object in the BL that changes periodically and the GUI should reflect the changes.
There are two issues that involve multithreading:
I need to make some of the logic
calls asynchronous so that they don't block the GUI.
Some of the events the GUI recevies are fired from non-GUI threads.
At what level is it best to handle the multithreading? My intuition says that the Presenter is the most suitable for that, am I right? Can you give me some example application that does what I need? And does it make sense for the presenter to hold a reference to the form so it can invoke delegates on it?
EDIT: The bounty will probably go to Henrik, unless someone gives an even better answer.

I would look at using a Task-based BLL for those parts that can be described as "background operations" (that is, they're started by the UI and have a definite completion point). The Visual Studio Async CTP includes a document describing the Task-based Asynchronous Pattern (TAP); I recommend designing your BLL API in this way (even though the async/await language extensions haven't been released yet).
For parts of your BLL that are "subscriptions" (that is, they're started by the UI and continue indefinitely), there are a few options (in order of my personal preference):
Use a Task-based API but with a TaskCompletionSource that never completes (or only completes by being cancelled as part of application shutdown). In this case, I recommend writing your own IProgress<T> and EventProgress<T> (in the Async CTP): the IProgress<T> gives your BLL an interface for reporting progress (replacing progress events) and EventProgress<T> handles capturing the SynchronizationContext for marshalling the "report progress" delegate to the UI thread.
Use Rx's IObservable framework; this is a good match design-wise but has a fairly steep learning curve and is less stable than I personally like (it's a pre-release library).
Use the old-fashioned Event-based Asynchronous Pattern (EAP), where you capture the SynchronizationContext in your BLL and raise events by queuing them to that context.
EDIT 2011-05-17: Since writing the above, the Async CTP team has stated that approach (1) is not recommended (since it somewhat abuses the "progress reporting" system), and the Rx team has released documentation that clarifies their semantics. I now recommend Rx for subscriptions.

It depends on what type of application you are writing - for example - do you accept bugs? What are your data requirements - soft realtime? acid? eventually consistent and/or partially connected/sometimes disconnected clients?
Beware that there's a distinction between concurrency and asynchronocity. You can have asynchronocity and hence call method call interleaving without actually having a concurrently executing program.
One idea could be to have a read and write side of your application, where the write-side publishes events when it's been changed. This could lead to an event driven system -- the read side would be built from the published events, and could be rebuilt. The UI could be task-driven - in that a task to perform would produce a command that your BL would take (or domain layer if you so wish).
A logical next step, if you have the above, is to also go event-sourced. Then you would recreate internal state of the write-model through what has been previously committed. There's a google group about CQRS/DDD that could help you with this.
With regards to updating the UI, I've found that the IObservable interfaces in System.Reactive, System.Interactive, System.CoreEx are well suited. It allows you to skip around different concurrent invocation contexts - dispatcher - thread pool, etc, and it interops well with the Task Parallel Library.
You'd also have to consider where you put your business logic -- if you go domain driven I'd say you could put it in your application as you'd have an updating procedure in place for the binaries you distribute anyway, when time comes to upgrade, but there's also the choice of putting it on the server. Commands could be a nice way to perform the updates to the write-side and a convenient unit of work when connection-oriented code fails (they are small and serializable and the UI can be designed around them).
To give you an example, have a look at this thread, with this code, that adds a priority to the IObservable.ObserveOnDispatcher(...)-call:
public static IObservable<T> ObserveOnDispatcher<T>(this IObservable<T> observable, DispatcherPriority priority)
{
if (observable == null)
throw new NullReferenceException();
return observable.ObserveOn(Dispatcher.CurrentDispatcher, priority);
}
public static IObservable<T> ObserveOn<T>(this IObservable<T> observable, Dispatcher dispatcher, DispatcherPriority priority)
{
if (observable == null)
throw new NullReferenceException();
if (dispatcher == null)
throw new ArgumentNullException("dispatcher");
return Observable.CreateWithDisposable<T>(o =>
{
return observable.Subscribe(
obj => dispatcher.Invoke((Action)(() => o.OnNext(obj)), priority),
ex => dispatcher.Invoke((Action)(() => o.OnError(ex)), priority),
() => dispatcher.Invoke((Action)(() => o.OnCompleted()), priority));
});
}
The example above could be used like this blog entry discusses
public void LoadCustomers()
{
_customerService.GetCustomers()
.SubscribeOn(Scheduler.NewThread)
.ObserveOn(Scheduler.Dispatcher, DispatcherPriority.SystemIdle)
.Subscribe(Customers.Add);
}
... So for example with a virtual starbucks shop, you'd have a domain entity that has something like a 'Barista' class, which produces events 'CustomerBoughtCappuccino' : { cost : '$3', timestamp : '2011-01-03 12:00:03.334556 GMT+0100', ... etc }. Your read-side would subscribe to these events. The read side could be some data model -- for each of your screens that present data -- the view would have a unique ViewModel-class -- which would be synchronized with the view in an observable dictionary like this. The repository would be (:IObservable), and your presenters would subscribe to all of that, or just a part of it. That way your GUI could be:
Task driven -> command driven BL, with focus on user operations
Async
Read-write-segregated
Given that your BL only takes commands and doesn't on top of that display a 'good enough for all pages'-type of read-model, you can make most things in it internal, internal protected and private, meaning you can use System.Contracts to prove that you don't have any bugs in it (!). It would produce events that your read-model would read. You could take the main principles from Caliburn Micro about the orchestration of workflows of yielded asynchronous tasks (IAsyncResults).
There are some Rx design guidelines you could read. And cqrsinfo.com about event sourcing and cqrs. If you are indeed interested in going beyond the async programming sphere into the concurrent programming sphere, Microsoft has released a well written book for free, on how to program such code.
Hope it helps.

I would consider the "Thread Proxy Mediator Pattern". Example here on CodeProject
Basically all method calls on your Adaptors run on a worker thread and all results are returned on the UI thread.

The recommended way is using threads on the GUI, and then update your controls with Control.Invoke().
If you don't want to use threads in your GUI application, you can use the BackgroundWorker class.
The best practice is having some logic in your Forms to update your controls from outside, normally a public method. When this call is made from a thread that is not the MainThread, you must protect illegal thread accesses using control.InvokeRequired/control.Invoke() (where control is the target control to update).
Take a look to this AsynCalculatePi example, maybe it's a good starting point.

Related

Threadsafe observer pattern

I'm writing an application for WPF in MVC pattern. The purpose of application is to display some data in the database and these data are being updated asynchronously.
I'm thinking about how to design the architecture, such that it will be thread-safe. In particular:
Each page (or its viewmodel) must be able to subscribe and unsubscribe from the service, which updates the database.
The service updating the database informs all subscribers, that new data arrived and that they should refresh their views.
Obviously, the page, which is just being closed should unsubscribe from the service and the page, which just appears, should (or may) subscribe.
I could put subscription inside a critical section, as well as broadcast about new data, but then imagine the following scenario (page ~= its viewmodel, that does not matter much here):
Service enters critical section to broadcast information about new data (in separate thread)
Page tries to enter critical section to unsubscribe (in main thread)
Service informs page about new data (in separate thread).
Page populates its fields and raises PropertyChange event (in separate thread).
PropertyChange event is marshalled to the main thread. Which waits for the critical section.
And it looks like a deadlock to me.
How can I safely design this architecture to avoid such deadlocks? Maybe pages should never unsubscribe? Or is there another way to secure threads such that they won't deadlock?
Given that the post is tagged WPF and WP-8.1 and the clarification in the comments, i would do the following:
Have the base Model class (the one with properties holding relevant data) implement INotifyPropertyChanged
Have the Model for ALL pages as ObservableCollection<BaseModel>. The model should also implement a mutex/lock property instantiated in the constructor.
Share the model across all viewmodels (e.g. share the instance of the model).
In the 'Service' performing async operation, i would only lock the section of the code that would Add or Remove items from the Model ObservableCollection using the lock object from the Model itself. This section MUST be placed in the Dispatcher.Invoke() or equivalent platform call. This ensures that it is only UI thread that is waiting to update the collection.
I would bind all the UI in the relevant pages to the model reference in the viewmodel.
This way the UI and viewmodels are careless to the specific service events thus eliminating the overhead of subscribing, and you also limit the duplication of the data if you share the model - even with 20 pages on screen, your service will perform a single update that is propagated to the UI and viewmodels by the powers of the framework (binding).
A simple solution could be: Do not do the unsubscribe operation in the UI thread. (In general do not block the UI thread.) Do it in async way, fire and forget.
Alternatively you may take a look to Rx (Reactive Extensions) what are exactly for this purpose: Implementing the observer pattern in multithreaded way.
Silently "just not unsubscribe" is probably not a good idea. Although I do not know your implementation details, if the event handlers are instance methods, then a reference to that instance implicitly will be kept by the service, and depending the reference chain maybe your page or other instances will be prevented to garbage collected.
"Or is there another way to secure threads such that they won't deadlock?" Currently in .NET framework there is no magic trick what automatically prevents deadlock. Other multithreaded environments may or may not provide an automatic deadlock resolution (note: not prevention) service what can detect a deadlock (after it happen) and automatically choose a victim. In .NET it could be an exception what occurs while your are waiting to a resource. (again this is not implemented yet)

How many models of Asynchronous development in .NET?

I am learning asynchronous programming using C# and I usually use BeginInvoke, but I am not very sure about the other methods of creating asynchronous application.
I have asked a question about this,see below link for more details:
How to return T value from BeginInvoke?
In above link, Gravell said that there are four models of asynchronous development
There's at least 4, then - a regular callback (non-APM, non-EAP) is also not uncommon
But Overflow said that there are three:
There are 3 models of asynchronous development in .NET
APM - (BeginXXX / EndXXX) which you are using here, when the long running task completes, it calls back into your code in the EndXXX method
EAP - Event based. In this model, when the long running task completes, an event is raised to inform your code.
TPL - New in .NET 4, this is the Task-based version. It looks most like synchronous programming to client code, using a fluent interface. Its calls back to your code using ContinueWith.
Anyone can help me on this?
I have searched google.com a lot, but actually they are using BeginInvoke most. thanks for your help.
Thread.Start - brutal
delegate.BeginInvoke/EndInvoke - 'old' standard
ThreadPool.QueueUserWorkItem - smart
TaskFactory.StartNew - the only way to do it correct (according to Patterns of parallel programming book | i recommend you to read it first for disambiguation)
There's a lot that can be caught in the term "asynchronous development."
For one, you could want to execute code on a background thread. I recently updated a blog post of mine contrasting several common approaches to executing code in the background. Here's the list, in order from most desirable to least:
Task (as used by async/await).
Task (as used by the Task Parallel Library).
BackgroundWorker.
Delegate.BeginInvoke.
ThreadPool.QueueUserWorkItem.
Thread
On another hand, you could want to represent an asynchronous operation (which may or may not be actual code executing on a background thread). In that case, there are several approaches, in order from most desirable to least:
Task (in the style of the Task-based Asynchronous Pattern (TAP))
IAsyncResult with Begin*/End* methods (which has the unfortunate name Asynchronous Programming Model (APM)).
A component written using the Event-based Asynchronous Pattern (EAP).
(As a side note, BackgroundWorker is EAP, and Delegate.BeginInvoke is APM).
On another hand, you could mean asynchronous programming in general, which can be interpreted to mean a reactive approach. In this case, there are only two approaches that I know of:
Reactive Extensions (Rx).
Event-based Asynchronous Pattern (EAP).
However, you could make a case that any event-driven program is reactive to some extent, so just handling UI events is a (simple) form of "asynchronous programming."
Also, these are only the common models. Any platform or library can add more. Here's some off the top of my head:
The Socket class has a special form of APM that can be used to minimize memory allocations. It works very similarly to APM but does not fit the pattern.
The WinRT runtime (coming in Windows 8) has its own representations of asynchronous operations (IAsyncOperation<TResult> and IAsyncInfo).
Windows Phone has specific support for a background agent, which permits you to run code in the background even if your app isn't currently running.
It will most certainly be useful to learn the methods Mikant described for asynchronous development. Just wanted to give you a heads up though that C# 5.0 is completely redesigning how the language deals with async. This will be its main theme along with introducing two new keywords, async and await. You simply call await on a long-running task and it will begin the task and return control to the calling method. Once the task is complete it proceeds with the rest of the code.
Here is an excellent video for the full details of its usage and explanation. It not only describes the old way of performing async operations but a complete review of the new style. It makes writing async applications a ton easier and much more readable with a natural flow.
This is the future of C# async behavior so well worth learning.
http://channel9.msdn.com/events/PDC/PDC10/FT09/

Reactive Extensions for component lib. consumed by desktop apps and other contexts.

I have built a component library that includes an executive class which does work on any number of threads and fires events from these threads. This is all good. Now I want to use my executive in a desktop app. (Winforms in the first instance, WPF later on) so I want to marshall all event calls back onto the UI thread. I know of a 3 ways to do this;
Check IsInvokedRequired/call Invoke in the handlers; This is lame IMO.
Create a decorator for the executive that uses the event base async model; Gives me the desired result, not very exciting though.
Use the WPF dispatcher; feels wrong to use a WPF class in Winforms app. or even more wrong to use it in the component lib.
I have spent the last hour or so reading up on Rx and I'm thinking the ideal solution might be to bake Rx into the executive and have the executive take (optionaly) a scheduler. This way the client of the executive can determine the behaviour with regard to the which thread/s the events are raised on and I get all of the other Rx goodness. Or perhaps create an RxExecutive that takes a Scheduler and encapsulates my existing executive to provide an Rx API.
Am I thinking along the right lines or have I missed the point?
Rx does provide a very nice way to access the UI thread in a Windows Forms app. You can use the full Rx library of observables, but if you just need an easy way to run things on the UI thread then using the ControlScheduler is a snap.
Assuming you have a form called form1 just do this:
var scheduler = new System.Reactive.Concurrency.ControlScheduler(form1);
scheduler.Schedule(() => { /* Do Stuff on UI thread */ });
Easy.
You don't have to use a reference to the form - you could use any control.
I believe the preferred pattern is to specify the scheduling SynchronizationContext. SynchronizationContexts are available for both WPF and WinForms applications, are used to schedule WF4 and WCF, and I'm sure are also used in other parts of the framework.
You are on the right track. Alternatively, you could have the users that care about the thread use ObserveOn. The advantage of this is that only the observer code is run on the needed thread.

WP7- Confused about network communication, cross thread access, and continuation passing

I'm porting a WPF app to WP7, and in the process I've had to refactor all the code that touches the network. The old code used the synchronous methods of the WebRequest object in background threads, but these methods no longer exist in WP7.
The result has been bewildering, and makes me feel like I'm doing something wrong. I've had to litter my views with thread dispatching code - the only alternative to this that I see is to supply the dispatcher to the lower tiers of the app, which would break platform-independence and muddy the boundary with the UI. I've lost the ability to make chained calls over the network from loops, and instead have callbacks invoking themselves. I've lost try/catch error handling and instead have OnSuccess and OnError callbacks everywhere. I'm now always unintentionally running code in background threads that are invoked by callbacks. I fondly remember the days when I was able to return values from methods.
I know continuation-passsing-style is supposed to be great, but I think all of the above has made the code more brittle and less readable, and has made threading issues more complex than they need to be.
Apologies if this question is vague, I'd just like to know if I'm missing some big picture here.
This is a limitation of Silverlight, which requires asynchronous network access (WCF proxy calls, WebClient, WebRequest, etc.). All synchronous network-reliant method calls have been removed from the framework.
To be crass: welcome to asynchronous programming. The only thing you did wrong was not making the calls asynchronous in the first place :)
I'm not 100% clear on the exact reasons MS removed the sync calls from web-dependent objects in Silverlight, but the explanations I hear always center on one or two reasons in some combination:
Browsers are architected on asynchronous network calls. Introducing synchronous calls would cause bad behavior/broken apps/crashes/etc.
If they gave everyone the "easy out" of making synchronous calls, the world would be littered with Silverlight apps that always froze while doing anything on the network, making Silverlight as a platform look bad.
That said - WCF proxies in Silverlight have the behavior that they always perform their callback on the calling thread. This is most often the UI thread, meaning you don't have to do any dispatching. I do not know if WebClient/WebRequest in Silverlight share this behavior.
As for the dispatcher, you could look into using a SynchronizationContext instead. The MVVM reference implementation in the MS Patterns and Practices Prism guidance does this - in the repository (data access class that actually makes calls out to an abstracted external service), they have a SynchronizationContext member that is initialized to System.Threading.SynchronizationContext.Current. This is the UI thread, if the constructor is called on the UI thread (it should be). All results from the service calls are then handled with mySynchronizationContext.Post.
Questions like this seem to behave like buses. You don't see any for ages then two come along almost at the same time. See this answer to a more concrete version of this question asked earlier today.
I have to I agree with you, continuation passing is tricky. A really useful technique is to borrow the C# yield return construct to create a machine that is able to maintain state between asynchronous operations. For a really good explanation see this blog by Jeremy Likness.
Personally I prefer a "less is more" approach so the AsyncOperationService is a very small chunk of code. You'll note that it has a single callback for both success and failure and there no interfaces to implement just a moderate delegate Action<Action<Exception>> which is typed as AsyncOperation to make it more convenient.
The basic steps to coding against this are:-
Code as if synchronous execution were possible
Create methods that return an AsyncOperation fpr only the smallest part that has to be asynchronous. Usually some WebRequest or WCF call but note just enough to get past the async bit, see me other answer for a good example.
Convert the synchronous "psuedo-code" to yeild these AsyncOperations and change the calling code to "Run" the resulting enumerable.
The final code looks quite similar to the synchronous code you might be more familar with.
As to accidentally running things on a background thread, that last answer included this useful AsyncOperation:-
public static AsyncOperation SwitchToUIThread()
{
return (completed => Deployment.Current.Dispatcher.BeginInvoke(() => completed(null)));
}
You can use that as the final yield in the run to ensure that code executing in the completed callback is executing on the UI thread. Its also useful to "flip" what is apparently synchronous code to be running on the UI thread when necessary.

How do I pass information from a ThreadPool.QueueUserWorkItem back to the UI thread?

I have a rather simple threading question.
I'm writing a simple utility that will run various SQL scripts based on parameters defined by the user.
In order to keep the UI responsive and provide feedback as to the status of the scripts that are being executed, I've decided that using ThreadPool.QueueUserWorkItem would be appropriate to handle the execution of the various scripts (via SMO.)
However, I'm a bit confused as to how I can relay the output information that SMO will return back to the UI thread.
For this utility, I'm using WPF and MVVM for the presentation. I'm thinking that I would have a ScriptWorker class that I could pass the parameters and locations and order in which to run the scripts to.
After I run each script, I'd like to somehow return the results to the UI thread so that it updates the output window and then I'd like for the worker to move to the next task.
I'm certain this is a basic question, but after looking at QueueUserWorkItem and seeing that I essentially start the work through a callback, I'm unsure how I'd accomplish what I'd like to accomplish.
I'm basing my assumptions off of this Microsoft article:
http://msdn.microsoft.com/en-us/library/3dasc8as(VS.80).aspx
Thanks for the info!
QueueUserWorkItem would technically work, but is extremely low-level. There are easier ways.
I recommend using the new Task feature of .NET 4.0. It does exactly what you want, including synchronizing the result or error conditions to another thread (the UI thread, in this case).
If .NET 4.0 is not an option, then I'd recommend either BackgroundWorker (if your background processing is not too complex), or asynchronous delegates such as Hans mentioned. If you use async delegates, then use the AsyncOperation class to marshal the results back to the UI thread.
The Task option is very nice because it handles parent/child tasks very naturally. BackgroundWorker can't be nested. Another consideration is cancellation; Task and BackgroundWorker have built-in support for cancellation, but for async delegates you'd have to do your own.
The only place where Task is a bit more complex than BackgroundWorker is in progress reporting. It's not quite as easy as BackgroundWorker, but I have a wrapper on my blog to minimize that.
To summarize, in order of preference:
Task - supports proper marshaling of errors, the concept of a result, cancellation, and parent/child nesting. Its one weakness is that progress reporting isn't simple (you have to create another Task and schedule it to the UI thread).
BackgroundWorker - supports proper marshaling of errors, the concept of a result, cancellation, and progress reporting. Its one weakness is that it doesn't support
parent/child nesting, and that limits its usage in APIs, e.g., for a business layer.
Delegate.BeginInvoke with AsyncOperation - supports proper marshaling of erros, the concept of a result, and progress reporting. However, there is not a built-in concept of cancellation (though it can be done by hand using a volatile bool). It also does not support parent/child nesting.
Delegate.BeginInvoke with SynchronizationContext - this is the same as option (3) except it uses SynchronizationContext directly. The code is slightly more complex, but the tradeoff is that parent/child nesting is supported. All other limitations are identical to option (3).
ThreadPool.QueueUserWorkItem with AsyncOperation or SynchronizationContext - supports the concept of progress reporting. Cancellation suffers from the same problem as option (3). Marshaling of errors is not easy (in particular, preserving the stack trace). Also, parent/child nesting is only possible if the SynchronizationContext is used instead of AsyncOperation. Furthermore, this option does not support the concept of a result, so any return value(s) need to be passed as arguments.
As you can see, Task is the clear winner. It should be used unless .NET 4.0 is not an option.
This article has a simple example of what you want.
To get back to the UI thread you need a reference to the ISynchronizeInvoke interface. The Form class for example implements this interface.
In pseudocode you could do something like this:
public class MyForm : Form
{
private OutputControl outputControl;
public void btnClick(...)
{
// Start a long running process that gives feedback to UI.
var process = new LongRunningProcess(this, outputControl);
ThreadPool.QueueUserWorkItem(process.DoWork);
}
}
class LongRunningProcess
{
// Needs a reference to the interface that marshals calls back to the UI
// thread and some control that needs updating.
public LongRunningProcess(ISynchonizeInvoke invoker,
OutputControl outputControl)
{
this.invoker = invoker;
this.outputControl = outputControl;
}
public void DoWork(object state)
{
// Do long-running job and report progress.
invoker.Invoke(outputControl.Update(...));
}
}
Note that the OutputControl in this example is a control and therefore also implements the ISynchronizeInvoke interface so you can also choose to call Invoke directly on this control.
The approach sketched above is rather low-level but gives you a lot of control, especially over how you want to report progress. BackgroundWorker gives you a more high-level solution but less control. You can only provide progress state via the untyped UserState property.

Categories