-
Notifications
You must be signed in to change notification settings - Fork 1
Async Package
This package provides extra features on top of those provided by TPL. It mainly focuses on 2 issues:
- Synchronizing access to shared resources (to compansate for the lack of
lock
and blocking in classic asynchronous work). - Controlling which code runs on which thread. Specifically, provide means that will allow encapsulation of synchronization context (see details area to understand what this means 😄 )
The async package has 2 sub packages:
- The Async Context Delegates Package - a set of classes that serve as delegates that are associated with a specific
TaskScheduler
- The Async Primitives Package - a set of classes that synchronize access to shared resources. This package is heavily influenced by Stephen Cleary's AsyncEx library.
In Addition the package contains the following classes:
-
AsyncContextRunner
- A wrapper aroundTaskSchduler
that helps to run code using that specific scheduler. Allows to run bothasync
methods and "normal" methods on the selected TaskSchduler -
DeferredTask<T>
- A fusion ofTask.FromResult<T>
andTaskCompletionSource<T>
. Creates a task that has a result that is known in advanced, but this task is not created completed. You complete it by calling the methodDeferredTask.Complete
. -
SingleThreadTaskScheduler
- A task scheduler that has it's own thread. It creates a thread when it is constructed, and schdules all tasks to this thread. - The Tasks class - A static class with some TPL related shortcuts and extension methods
MVVM development relies heavily on events and callbacks. A view model defines a set of events to notify the view of changes (such as PropertyChanged
, CollectionChanged
in collections, CanExecuteChanged
in commands, ErrorsChanged
in validation, and the list goes on). It also registers to events that model services expose in order to react to changes in data model. If you use the reactive pattern, you may not use events, but you will pass callbacks to observables.
When a ViewModel, or a service provides a delegate to another service (either by registering to events, or by providing callbacks any other way) there is a problem with encapsulation, since the code that decides on which thread to run the delegate belongs to the service. A more correct approach will be to allow each object to decide where to run it's code. So if Object A registers to an event on Object B, Object A should be the one to decide which thread will run the event handler. Which is not the default way in C#.
So, as said above, one of the 2 targets of the kit's async package, is to provide easy means to allow such seperation of concerns. Services should decide which threads their code should run in, and when they expose events, each object that registers to the event should be able to control the thread that runs the handler.