1

I am working with C# language and was working on getting data out of cassandra so I was working with below code which gets data from Cassandra and it works fine.

Only problem I have is in my ProcessCassQuery method - I am passing CancellationToken.None to my requestExecuter Function which might not be the right thing to do.

And I need to timeout the query if it takes more than 800 milliseconds so how can I use CancellationToken here properly to timeout the query? Cassandra driver doesn't handle CancellationToken yet so I need to do this outside through some other ways. This code will be called at a very high throughput so it needs to be efficient while timing out the call..

/**
 *
 * Below method does multiple async calls on each table for their corresponding id's by limiting it down using Semaphore.
 *
 */
private async Task<List<T>> ProcessCassQueries<T>(IList<int> ids, Func<CancellationToken, int, Task<T>> mapperFunc, string msg) where T : class
{
    var tasks = ids.Select(async id => 
    {
        await semaphore.WaitAsync();
        try
        {
            return await ProcessCassQuery(ct => mapperFunc(ct, id), msg);
        }
        finally
        {
            semaphore.Release();
        }
    });

  return (await Task.WhenAll(tasks)).Where(e => e != null).ToList();
}

// this might not be good idea to do it. how can I improve below method?
private Task<T> ProcessCassQuery<T>(Func<CancellationToken, Task<T>> requestExecuter, string msg) where T : class
{
    return requestExecuter(CancellationToken.None);
}
dragons
  • 549
  • 1
  • 8
  • 24
  • What about adding a second ```Task``` which does nothing but ```Task.Delay``` for the specified amount of time? You'd have to change ```.WhenAll``` to ```.WhenAny```. You could then check if the returned ```Task``` is the timeout task and handle it accordingly. – devsmn Jun 05 '20 at 06:25
  • Does this answer your question? [Asynchronously wait for Task to complete with timeout](https://stackoverflow.com/questions/4238345/asynchronously-wait-for-taskt-to-complete-with-timeout) – the.Doc Jun 05 '20 at 13:36
  • @imsmn what's the difference between your suggestion vs suggestion by Andrey below? Which one is better though? – dragons Jun 05 '20 at 19:37

1 Answers1

3

You can use the following code:

// this might not be good idea to do it. how can I improve below method?
private async Task<T> ProcessCassQuery<T>(Func<CancellationToken, Task<T>> requestExecuter, string msg) where T : class
{
    using var cts = new CancellationTokenSource();
    cts.CancelAfter(TimeSpan.FromMilliseconds(800));
    return await requestExecuter(cts.Token);
}
Andrey Nasonov
  • 2,619
  • 12
  • 26
  • thanks. yeah this works fine. curious to know whether this is the best way here to timeout my call? I am just worried since my method will be called at a very high throughput. – dragons Jun 05 '20 at 17:35