dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.37k stars 4.75k forks source link

Add TimeSpan overloads to System.TimeoutException #27060

Open MarcoRossignoli opened 6 years ago

MarcoRossignoli commented 6 years ago

Rationale

I'm working on a project where i need to heavily use TimeoutException.
Today we cannot pass TimeSpan to TimeoutException, like ParamName for ArgumentException. Could be useful add overloads to pass TimeSpan when throw exception, this could be useful for some reason:

Proposed API

public class TimeoutException
{
    public TimeoutException(TimeSpan timeout) {}
    public TimeoutException(string message, TimeSpan timeout) {}
    public TimeoutException(string message, TimeSpan timeout, Exception innerException) {}
    public virtual TimeSpan? Timeout { get; }
}

Usage


while(true)
{
    ...retry logic...
    try
    {
        // print does some works...supervision printer, read RFID, set parameters, print something
        // every operation could timeout, but supervision timeout are recoverable other 
        // not always or we cannot wait too much(if timeout is for example > 30 seconds)
        printer.Print();
    }
    catch(TimeoutException ex)
    {
        // we can recover supervision timeout
        if (ex.Timeout.HasValue && ex.Timeout <= TimeSpan.FromSeconds(3))
        {
            continue;
        }
        else
            throw;
    }
}
TimeSpan timeoutWait = TimeSpan.Zero;
while (true)
{
    try
    {
        return printer.GetStatus();
    }
    catch (TimeoutException ex)
    {
        if (ex.Timeout.HasValue)
        {
            timeoutWait = timeoutWait.Add(ex.Timeout.Value);

            // Wait for no more than 30 seconds
            // I know timeout could be > 30 sec, but retry as much as possible, best we can
            // Timeout threshold could change in future
            // Also in subclassed exception scenario...threshold could change          
            if (timeoutWait >= TimeSpan.FromSeconds(30))
                throw;

            continue;
        }
    }
}

Extra

I didn't found any issue with this on repo , but i suspect that this is not new topic. I found on codebase an implementation for RegEx

danmoseley commented 6 years ago

Can you clarify your retry scenario? You catch TE and then examine the TimesSpan on it and decide whether to retry somehow? Maybe a code snippet would help.

MarcoRossignoli commented 6 years ago

@danmosemsft updated, i'm working with hardware printers handled by a json/rpc server(provided by printer sdk). Server is not so reliable...and sometimes some type of command works after some retry but not always and not always behave in the same way(for example i know that if i retry some command for more than 30 seconds i need to "reset" something to go on). I could(and for now) resolve subclassing exceptions, but knowing timeout nature code could be less and more clear maybe.