![](/img/trans.png)
[英]BackgroundService Await Task.Delay in infinite loop leaks SqlConnection objects hard
[英]Doing await Task.Delay in an infinite loop
我有下面的代码,它将执行Action operation
,如果其中发生异常,将重试它。
因为代码正在await Task.Delay(delay);
在while(true)
,我在犹豫这是否会导致任何内存泄漏? 喜欢创建无限threads
吗?
这段代码可以正常工作,但是我只担心可能发生内存泄漏? 如果有人可以分享一些见解,我将不胜感激。
public class OperationWithBasicRetry
{
public async Task StartOperationAsync(Action operation, TimeSpan delay, int retryCount)
{
int currentRetry = 0;
while(true)
{
try
{
operation();
// Success
break;
}
catch (Exception ex)
{
if (++currentRetry > retryCount)
{
throw;
}
}
await Task.Delay(delay);
}
}
}
这很安全。
这是一个async
方法,因此编译器将其切碎并将其变成状态机。 作为非常粗略的近似来说明这一点,您可以认为编译后的代码看起来像这样:
private class State
{
public int currentRetry;
public Action operation;
public TimeSpan delay;
public int retryCount;
public TaskCompletionSource<object> tcs;
private void StartOperationAsyncImpl(object unused)
{
try
{
operation();
tcs.SetResult(null);
return;
}
catch (Exception ex)
{
if (++currentRetry > retryCount)
{
tcs.SetException(ex);
}
}
// I'm ignoring the delay bit, because it has no affect on the point
// I'm trying to make.
ThreadPool.QueueUserWorkItem(StateOperationAsyncImpl);
}
}
public Task StartOperationAsync(Action operation, TimeSpan delay, int retryCount)
{
State state = new State();
state.currentRetry = 0;
state.operation = operation;
state.delay = delay;
state.retryCount = retryCount;
state.tcs = new TaskCompletionSource<object>();
ThreadPool.QueueUserWorkItem(state.StartOperationAsyncImpl);
return state.tcs;
}
当然,实际的已编译代码看起来并不像这样( 看起来像这样 ),但这说明了我的观点。
这里没有递归。 甚至没有无限循环。 您有一个方法,该方法在被调用时会尝试执行您的操作。 如果失败,则将其排队到ThreadPool上并返回。 对ThreadPool.QueueUserWorkItem
调用将立即返回,并且不会等到工作完成。
ThreadPool.QueueUserWorkItem
也不创建新线程-它将要由预先存在的线程池执行的工作排队。
(在有人发表评论之前-我知道实际的编译后的代码不会直接使用ThreadPool.QueueUserWorkItem
,但可能会使用默认的TaskScheduler,它会在内部调用ThreadPool.UnsafeQueueUserWorkItem
,因此是一个很好的近似值)。
我认为不会,因为一旦满足retryCount
条件,它要么通过break要么通过throw退出循环。 取决于您的retryCount
,这将导致内存泄漏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.