Better way to write retry logic without goto [dupl

2019-01-26 10:02发布

This question already has an answer here:

Is there a better way to write this code without using goto? It seems awkward, but I can't think of a better way. I need to be able to perform one retry attempt, but I don't want to duplicate any code.

public void Write(string body)
{
    bool retry = false;
RetryPoint:
    try
    {
        m_Outputfile.Write(body);
        m_Outputfile.Flush();
    }
    catch (Exception)
    {
        if( retry )
            throw; 
        // try to re-open the file...
        m_Outputfile = new StreamWriter(m_Filepath, true);
        retry = true;
        goto RetryPoint;
    }
}

标签: c# .net goto
7条回答
闹够了就滚
2楼-- · 2019-01-26 10:14

Here is the basic logic that I would use instead of a goto statement:

bool succeeded = false;
int tries = 2;

do
{
    try
    {
        m_Outputfile = new StreamWriter(m_Filepath, true);
        m_Outputfile.Write(body); 
        m_Outputfile.Flush(); 
        succeeded = true;
    }
    catch(Exception)
    {
        tries--;
    }
}
while (!succeeded && tries > 0);

I just added # of tries logic, even though the original question didn't have any.

查看更多
SAY GOODBYE
3楼-- · 2019-01-26 10:17

@Michael's answer (with a correctly implemented out catch block) is probably the easiest to use in your case, and is the simplest. But in the interest of presenting alternatives, here is a version that factors the "retry" flow control into a separate method:

// define a flow control method that performs an action, with an optional retry
public static void WithRetry( Action action, Action recovery )
{
    try {
        action(); 
    }
    catch (Exception) {
        recovery();
        action();
    }
}

public void Send(string body)
{
    WithRetry(() =>
    // action logic:
    {
       m_Outputfile.Write(body);
       m_Outputfile.Flush();
    },
    // retry logic:
    () =>
    {
       m_Outputfile = new StreamWriter(m_Filepath, true);
    });
}

You could, of course, improve this with things like retry counts, better error propagation, and so on.

查看更多
Luminary・发光体
4楼-- · 2019-01-26 10:22

with a boolean

public void Write(string body)
{
        bool NotFailedOnce = true;            
        while (true)
        {
            try
            {
                 _outputfile.Write(body);
                 _outputfile.Flush();           
                 return;                    
            }
            catch (Exception)
            {
                NotFailedOnce = !NotFailedOnce;
                if (NotFailedOnce)
                {
                    throw;
                }
                else
                {
                     m_Outputfile = new StreamWriter(m_Filepath, true);
                }
            }
      }        
}
查看更多
神经病院院长
5楼-- · 2019-01-26 10:26

What if you put it in a loop? Something similar to this, maybe.

while(tryToOpenFile)
{
    try
    {
        //some code
    }
    catch
    {
    }
    finally
    {
        //set tryToOpenFile to false when you need to break
    }
}
查看更多
Ridiculous、
6楼-- · 2019-01-26 10:30
public void Write(string body, bool retryOnError)
{
    try
    {
        m_Outputfile.Write(body);
        m_Outputfile.Flush();
    }
    catch (Exception)
    {
        if(!retryOnError)
            throw; 
        // try to re-open the file...
        m_Outputfile = new StreamWriter(m_Filepath, true);
        Write(body, false);
    }
}
查看更多
再贱就再见
7楼-- · 2019-01-26 10:30

Try something like the following:

int tryCount = 0;
bool succeeded = false;

while(!succeeded && tryCount<2){
    tryCount++;
    try{
        //interesting stuff here that may fail.

        succeeded=true;
    } catch {
    }
}
查看更多
登录 后发表回答