StackExchange.Redis directly supports timeout of synchronous operations, but for asynchronous operations, it is recommended
to use the inbuilt framework support for cancellation and timeouts, i.e. the WaitAsync
family of methods. This allows the caller to control timeout (via TimeSpan
), cancellation (via CancellationToken
), or both.
Note that it is possible that operations will still be buffered and may still be issued to the server after timeout/cancellation means that the caller isn’t observing the result.
Timeouts are probably the most common cancellation scenario:
var timeout = TimeSpan.FromSeconds(5);
await database.StringSetAsync("key", "value").WaitAsync(timeout);
var value = await database.StringGetAsync("key").WaitAsync(timeout);
You can also use CancellationToken
to drive cancellation, identically:
CancellationToken token = ...; // for example, from HttpContext.RequestAborted
await database.StringSetAsync("key", "value").WaitAsync(token);
var value = await database.StringGetAsync("key").WaitAsync(token);
These two concepts can be combined so that if either cancellation or timeout occur, the caller’s operation is cancelled:
var timeout = TimeSpan.FromSeconds(5);
CancellationToken token = ...; // for example, from HttpContext.RequestAborted
await database.StringSetAsync("key", "value").WaitAsync(timeout, token);
var value = await database.StringGetAsync("key").WaitAsync(timeout, token);
If you want a timeout to apply to a group of operations rather than individually, then you
can using CancellationTokenSource
to create a CancellationToken
that is cancelled after a
specified timeout. For example:
var timeout = TimeSpan.FromSeconds(5);
using var cts = new CancellationTokenSource(timeout);
await database.StringSetAsync("key", "value").WaitAsync(cts.Token);
var value = await database.StringGetAsync("key").WaitAsync(cts.Token);
This can additionally be combined with one-or-more cancellation tokens:
var timeout = TimeSpan.FromSeconds(5);
CancellationToken token = ...; // for example, from HttpContext.RequestAborted
using var cts = CancellationTokenSource.CreateLinkedTokenSource(token); // or multiple tokens
cts.CancelAfter(timeout);
await database.StringSetAsync("key", "value").WaitAsync(cts.Token);
var value = await database.StringGetAsync("key").WaitAsync(cts.Token);