-
Notifications
You must be signed in to change notification settings - Fork 4
Asynchrony
All methods that make blocking I/O requests have non-blocking asynchronous equivalents that are suffixed with Async
and return TPL Task
objects. It's strongly recommended that clients use the asynchronous methods whenever possible to avoid wasting valuable threads.
Note: The TPL was introduced .NET 4.0 so the .NET 2.0 and 3.5 versions of this library don't support asynchronous methods. Also note that Silverlight, Windows 8 and Windows Phone don't support blocking I/O operations, so only the asynchronous versions are available in those versions of this library.
Client side asynchrony should not be confused with server side SData asynchronous operations, where clients provide a tracking token that they can use to monitor long running services and batch operations in subsequent requests. This library is able to use this server side feature but doesn't provide any special high level APIs.
The easiest way to take advantage of asynchrony is by using the async
/await
keywords that were introduced in C# 5.0. The following example asynchronously requests all contact statuses then groups and counts them in memory once the data is received.
var client = new SDataClient("http://example.com/sdata/slx/dynamic/-/")
{
UserName = "admin",
Password = "password"
};
var statuses = await client.Query<Contact>()
.Select(a => a.Status)
.ToListAsync();
var counts = statuses.GroupBy(status => status)
.ToDictionary(grp => grp.Key, grp => grp.Count());
The asynchronous methods are also available when using earlier C# versions however the task object has to be interacted with directly. The following example processes the list of contact status in the previous example using a continuation lambda passed to the ContinueWith
method.
var counts = client.Query<Contact>()
.Select(a => a.Status)
.ToListAsync()
.ContinueWith(task =>
task.Result.GroupBy(status => status)
.ToDictionary(grp => grp.Key, grp => grp.Count()));
All asynchronous methods follow the standard cancellation pattern by providing an optional CancellationToken
argument. The following example cancels an asynchronous contact query immediately after making it and outputs the task status which should be Canceled
.
var cancelSource = new CancellationTokenSource();
var task = client.Query<Contact>().ToListAsync(cancelSource.Token);
cancelSource.Cancel();
Console.WriteLine(task.Status);
The asynchronous versions of the standard greedy LINQ conversion operators (ToListAsync
, ToArrayAsync
, etc) only return once the sequence of results has been fully paged to the end. Alternatively each individual page of results can be immediately processed by simply iterating over the query object directly. The following example synchronously requests each page of contacts and displays their names as they arrive.
foreach (var contact in client.Query<Contact>())
{
Console.WriteLine(contact.FullName);
}