Create two competing tasks: the actual API call and a simple time delay representing your threshold.
int thresholdMs = 2000; // Your N milliseconds
var apiCallTask = HttpClient.GetAsync(url); // The API call task
var delayTask = Task.Delay(thresholdMs); // The monitoring timer
Use Task.WhenAny to wait for the fastest task. If the delay finishes first, the API call has exceeded the threshold, and you log a warning.
var completedTask = await Task.WhenAny(apiCallTask, delayTask);
if (completedTask == delayTask)
{
// LOG ENTRY: The threshold was breached.
// The apiCallTask is still running in the background.
log.LogWarning("API call is slow, still waiting...");
}
Regardless of whether the warning was logged, you must always await the original apiCallTask to make sure the call finishes and its result is handled.
// Wait for the API call to finally finish
try
{
var response = await apiCallTask;
// ... process final result
}
catch (Exception ex)
{
// ... handle exceptions
}
Advice. There can be a lot of ways to handle this. I'd start with Activity/ActivitySource just for the abstractions, and either check for long calls in whatever monitoring I use, or create a custom listener that triggers a notification or log if an activity isn't finished/disposes in X seconds.