Asynchronous Support
All distributed methods on all Ignite.NET APIs can be executed either synchronously or asynchronously. These methods are presented as DoSomething/DoSomethingAsync pairs. Async methods follow Task-based Asynchronous Pattern: they return System.Threading.Task and can be awaited using C# 5 "await" keyword.
Async methods that support cancellation have overloads with CancellationToken
parameter.
Compute Grid Example
The example below illustrates the difference between synchronous and asynchronous computations.
ICompute compute = ignite.GetCompute();
// Execute a job and wait for the result.
string res = compute.Call(new ComputeFunc());
Console.WriteLine(res);
Here is how you would make the above invocation asynchronous:
// Start asynchronous operation and obtain a Task that represents it
Task<string> asyncRes = compute.CallAsync(new ComputeFunc());
// Synchronously wait for the task to complete and obtain result
Console.WriteLine(asyncRes.Result);
// OR use C# 5 await keyword
Console.WriteLine(await asyncRes);
// OR use continuation
asyncRes.ContinueWith(task => Console.WriteLine(task.Result));
Data Grid Example
Here is the data grid example for synchronous and asynchronous invocations.
ICache<int, string> cache = ignite.GetCache<int, string>("myCache");
CacheResult<string> val = cache.GetAndPut(1, "1");
Here is how you would make the above invocation asynchronous.
// Start asynchronous operation and obtain a Task that represents it
Task<CacheResult<string>> asyncVal = cache.GetAndPutAsync(1, "1");
// Synchronously wait for the task to complete and obtain result
Console.WriteLine(asyncVal.Result.Success);
// Use C# 5 await keyword
Console.WriteLine((await asyncVal).Success);
// Use continuation
asyncVal.ContinueWith(task => Console.WriteLine(task.Result.Success));
Async Continuations
Async operations in Ignite are completed from special system threads. These threads have the following limitations:
- Ignite APIs should not be used
- Heavy operations should not be performed
Your code can end up in Ignite system thread when you use ConfigureAwait(false)
with async
keyword:
var cache = ignite.GetCache<int, int>("ints");
await cache.PutAsync(1, 1).ConfigureAwait(false);
// All the code below executes in Ignite system thread.
// Do not access Ignite APIs from here.
If you need to perform multiple awaited operations, do not use ConfigureAwait(false)
.
For Console, ASP.NET Core, and some other types of applications the default System.Threading.SynchronizationContext
is not set, so a custom SynchronizationContext
is required to avoid running continuations on Ignite system threads. The simplest way is to derive from SynchronizationContext
class like this:
class Program
{
public static async Task<int> Main()
{
// Run async continuations on .NET Thread Pool threads.
SynchronizationContext.SetSynchronizationContext(
new ThreadPoolSynchronizationContext());
using (var ignite = Ignition.Start())
{
var cache = ignite.GetOrCreateCache<int, string>("my-cache");
await cache.PutAsync(1, "Test1");
await cache.PutAsync(2, "Test2");
await cache.PutAsync(3, "Test3");
}
return 0;
}
}
class ThreadPoolSynchronizationContext : SynchronizationContext
{
// No-op.
// Don't use SynchronizationContext class directly because optimization
// in the Task class treats that the same way as null context.
}
Updated over 5 years ago