有没有更好的方法来编写这段代码而不使用goto?这看起来很尴尬,但我想不出更好的方法.我需要能够执行一次重试尝试,但我不想复制任何代码.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*ter 15
这是我将使用的基本逻辑,而不是goto语句:
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);
Run Code Online (Sandbox Code Playgroud)
我刚刚添加了尝试逻辑,尽管原始问题没有.
迈克尔的解决方案并不能完全满足要求,即重试固定次数,抛出最后一次失败.
为此,我建议一个简单的for循环,倒计时.如果成功,请退出break(或者,如果方便的话,返回).否则,让catch检查索引是否为0.如果是,请重新抛出而不是记录或忽略.
public void Write(string body, bool retryOnError)
{
for (int tries = MaxRetries; tries >= 0; tries--)
{
try
{
_outputfile.Write(body);
_outputfile.Flush();
break;
}
catch (Exception)
{
if (tries == 0)
throw;
_outputfile.Close();
_outputfile = new StreamWriter(_filepath, true);
}
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,返回会很好,但我想展示一般情况.
@Michael 的答案(正确实现了 catch 块)可能是您的案例中最容易使用的,也是最简单的。但为了展示替代方案,这里有一个将“重试”流控制分解为单独方法的版本:
// 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);
});
}
Run Code Online (Sandbox Code Playgroud)
当然,您可以通过重试计数、更好的错误传播等来改进这一点。
| 归档时间: |
|
| 查看次数: |
6334 次 |
| 最近记录: |