Search code examples
c#mongodbtimelimitcounting

In C#, how can I timebox a counting operation?


We have a method which, among other things, returns a count of documents in a MongoDb collection. When there is a lot of data and not many filters, this can take an insanely long time.

Well, it turns out, most of the time we don't actually need this value, or when we do it can be returned in a reasonable amount of time (because either the collection has less records, the request has more filters, or we have been able to anticipate the need and apply suitable filters.

I would like to somehow wrap await collection.CountDocumentsAsync(filters, cancellationToken: cancellationToken); in some sort of function which would limit counting to half a second.

If it gets a result, return it.
It not, return Int32.MaxValue instead.

Is this possible? If so, how?


Solution

  • You can use a cancellation token with a time limit. Create a new token using a CancellationTokenSource that lets you specify the maximum duration. For example:

    var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
    
    var documentCount = int.MaxValue;
    
    try
    {
        documentCount = await collection.CountDocumentsAsync(filters,
            cancellationToken: cts.Token);
    }
    catch(TaskCanceledException)
    {
        // Or ignore this if you don't care
        Console.WriteLine("Task lasted longer than 30 seconds");    
    }
    
    // Now documentCount will be equal to int.MaxValue 
    // if the operation takes longer than 30 seconds