- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我开发了一个库,它为工作项实现了生产者/消费者模式。工作出队,并且为每个出队的工作项目启动了一个单独的任务,失败和成功的延续。
任务继续在完成(或失败)其工作后重新排队工作项。
全馆共用一个中央CancellationTokenSource
,这是在应用程序关闭时触发的。
我现在面临重大的内存泄漏。如果任务是使用取消标记作为参数创建的,那么任务似乎会保留在内存中,直到取消源被触发(然后被释放)。
这可以在此示例代码 (VB.NET) 中重现。主要任务是包装工作项的任务,继续任务将处理重新安排。
Dim oCancellationTokenSource As New CancellationTokenSource
Dim oToken As CancellationToken = oCancellationTokenSource.Token
Dim nActiveTasks As Integer = 0
Dim lBaseMemory As Long = GC.GetTotalMemory(True)
For iteration = 0 To 100 ' do this 101 times to see how much the memory increases
Dim lMemory As Long = GC.GetTotalMemory(True)
Console.WriteLine("Memory at iteration start: " & lMemory.ToString("N0"))
Console.WriteLine(" to baseline: " & (lMemory - lBaseMemory).ToString("N0"))
For i As Integer = 0 To 1000 ' 1001 iterations to get an immediate, measurable impact
Interlocked.Increment(nActiveTasks)
Dim outer As Integer = i
Dim oMainTask As New Task(Sub()
' perform some work
Interlocked.Decrement(nActiveTasks)
End Sub, oToken)
Dim inner As Integer = 1
Dim oFaulted As Task = oMainTask.ContinueWith(Sub()
Console.WriteLine("Failed " & outer & "." & inner)
' if failed, do something with the work and re-queue it, if possible
' (imagine code for re-queueing - essentially just a synchronized list.add)
' Does not help:
' oMainTask.Dispose()
End Sub, oToken, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default)
' if not using token, does not cause increase in memory:
'End Sub, TaskContinuationOptions.OnlyOnFaulted)
' Does not help:
' oFaulted.ContinueWith(Sub()
' oFaulted.Dispose()
' End Sub, TaskContinuationOptions.NotOnFaulted)
Dim oSucceeded As Task = oMainTask.ContinueWith(Sub()
' success
' re-queue for next iteration
' (imagine code for re-queueing - essentially just a synchronized list.add)
' Does not help:
' oMainTask.Dispose()
End Sub, oToken, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default)
' if not using token, does not cause increase in memory:
'End Sub, TaskContinuationOptions.OnlyOnRanToCompletion)
' Does not help:
' oSucceeded.ContinueWith(Sub()
' oSucceeded.Dispose()
' End Sub, TaskContinuationOptions.NotOnFaulted)
' This does not help either and makes processing much slower due to the thrown exception (at least one of these tasks is cancelled)
'Dim oDisposeTask As New Task(Sub()
' Try
' Task.WaitAll({oMainTask, oFaulted, oSucceeded, oFaultedFaulted, oSuccededFaulted})
' Catch ex As Exception
' End Try
' oMainTask.Dispose()
' oFaulted.Dispose()
' oSucceeded.Dispose()
' End Sub)
oMainTask.Start()
' oDisposeTask.Start()
Next
Console.WriteLine("Memory after creating tasks: " & GC.GetTotalMemory(True).ToString("N0"))
' Wait until all main tasks are finished (may not mean that continuations finished)
Dim previousActive As Integer = nActiveTasks
While nActiveTasks > 0
If previousActive <> nActiveTasks Then
Console.WriteLine("Active: " & nActiveTasks)
Thread.Sleep(500)
previousActive = nActiveTasks
End If
End While
Console.WriteLine("Memory after tasks finished: " & GC.GetTotalMemory(True).ToString("N0"))
Next
CancellationCallbackInfo
.
TaskContinuationOptions
),那么似乎存在内存泄漏。如果只有一个继续运行,那么我没有观察到内存泄漏。
TaskContinuationOptions
的情况下进行单个延续。并在那里处理父任务的状态:
oMainTask.ContinueWith(Sub(t)
If t.IsCanceled Then
' ignore
ElseIf t.IsCompleted Then
' reschedule
ElseIf t.IsFaulted Then
' error handling
End If
End Sub)
最佳答案
一些观察
oFaulted
任务,泄漏对我来说消失了。如果您更新代码以具有 oMainTask
故障,使oFaulted
任务运行并且 oSucceeded
任务没有运行,然后注释掉 oSucceeded
防止泄漏。 oCancellationTokenSource.Cancel()
在所有任务运行后,内存释放。 Dispose 没有帮助,也没有 Dispose 取消源与任务的任何组合。 Dim continuation As Task =
oMainTask.ContinueWith(
Sub(antecendent)
If antecendent.Status = TaskStatus.Faulted Then
'Handle errors
ElseIf antecendent.Status = TaskStatus.RanToCompletion Then
'Do something else
End If
End Sub,
oToken,
TaskContinuationOptions.None,
TaskScheduler.Default)
关于.NET TPL CancellationToken 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30029462/
原因是如果它是CancellationToken.None,我需要添加一个超时(所以一个新的CancellationToken 来自CancellationTokenSource),例如 if (ca
我认为 RunAsync 方法采用 CancellationToken 作为参数,这很棒。 不幸的是,根据我的观察,我从未被取消。 当然,取消RunAsync 方法并调用OnCloseAsync 会有
我正在尝试使用取消标记从另一个线程中跳出循环: using System; using System.Threading; using System.Threading.Tasks; namespac
我对 AzureFunctions 还很陌生,所以请原谅我问一个简单的问题...... 我有以下代码,当队列中有一个项目时会触发该代码 [FunctionName("ProcessCompanies"
我有以下异步函数: private async Task ValidateFtpAsync() { return await Task.Run( ()
.NET 中的 TPL 新手。尝试了解 CancellationToken 以及它们如何收到取消正在执行的任务的信号。下面的代码只传输一个被取消的任务,因为相同的 token 被传递给两个任务。我的假
我有一个计时器,每 2 秒启动 2 个任务...我在一个简单的列表中跟踪这些任务(这样我就可以在停止应用程序时等待它们完成)。 任务有效地转到数据库,运行几个更新并完成。 任务本身的运行时间不会超过一
在没有搭建快速测试台的情况下;我想我会很快问 SO 看看是否有人知道这个答案。 此外,它可能还有一个额外的好处,即通知可能遇到类似情况的其他用户。 假设我有一个长期存在的 CancellationTo
我的 Xamarin.Forms 项目出现以下错误: at System.Threading.CancellationToken.ThrowOperationCanceledException (
我对如何为以下情况实现取消 token 感到有些困惑。 假设我有一个方法,它有一个取消 token ,没有像这样指定超时。 public static async Task DoSomeAsyncTh
.NET 4.5.1:看来,我无法使用 CancellationTokenSource 内置超时取消在任务中运行的阻塞方法。 class Program { static void Main(
我想使用锁或类似的同步来保护临界区。同时我想听一个CancellationToken。 现在我正在使用这样的互斥锁,但互斥锁的性能不佳。我可以使用任何其他同步类(包括新的 .Net 4.0)来代替互斥
这是我的情况: private CancellationTokenSource cancellationTokenSource; private CancellationToken c
我有一个用于各种任务的 token ,我需要更好地管理它们的取消,以便收到我可以使用的取消通知: token.Register(RegisterMethod); 我怎样才能删除这个“订阅”?有什么办法
我启动一个任务,然后启动其他任务等等。给定那棵树,如果任何任务失败,则整个操作的结果都是无用的。我正在考虑使用取消 token 。令我惊讶的是, token 没有“CancelThisToken()”
我今天早上一直在研究 Async CTP,并且有一个带有 button 和 label 的简单程序。单击按钮,它开始更新标签,停止按钮,它停止写入标签。但是,我不确定如何重置 Cancellation
我有一些异步代码,我想将其添加到 CancellationToken 中。但是,有很多实现不需要这样做,所以我想要一个默认参数 - 也许是 CancellationToken.None。然而, Tas
这段代码执行时 cancellationToken.ThrowIfCancellationRequested(); try catch block 不处理异常。 public Enumerab
最近我遇到了a Microsoft interface使用一个非常不寻常的 API: public interface IHostApplicationLifetime { public Ca
CancellationToken.CanBeCanceled 上的文档描述了它的作用,但没有提到它什么时候可能是假的。因此,我不完全清楚何时应该注意此属性。 在什么情况下它可以是假的,我应该什么时候
我是一名优秀的程序员,十分优秀!