【发布时间】:2021-12-03 04:51:53
【问题描述】:
我有一个组件,它可以执行长时间的异步操作,并且可以在该操作完成之前被销毁。在这种情况下,我只想停止运行这些操作并忘记它们,没有任何例外。我有下一个例子:
private CancellationTokenSource destroyTokenSource = new CancellationTokenSource();
private async void RunExample()
{
await LongAction().MuteOnDestroy(destroyTokenSource.Token);
// ... actions that should not be performed with destroyed object
}
private async Task<bool> LongAction()
{
// some very long actions
return true;
}
// ...
public static class TaskExtension
{
public static Task<T> MuteOnDestroy<T>(this Task<T> task, CancellationToken destroyToken)
{
var promise = new TaskCompletionSource<T>();
task.ContinueWith(t =>
{
if (!destroyToken.IsCancellationRequested)
{
switch (t.Status)
{
case TaskStatus.Canceled:
promise.SetCanceled();
break;
case TaskStatus.Faulted:
promise.SetException(t.Exception!);
break;
case TaskStatus.RanToCompletion:
promise.SetResult(t.Result);
break;
}
}
}, TaskContinuationOptions.ExecuteSynchronously);
return promise.Task;
}
}
我假设永远不会完成的异步方法(在此示例中为 RunExample 方法)(destroyToken.IsCancellationRequested == true)会导致内存泄漏,但我不确定,因为我不知道“永远等待”的延续在哪里" 方法被存储。
会导致内存泄漏吗?
【问题讨论】:
-
async void 用于事件处理程序。
RunExample方法是事件处理程序吗?如果没有,是否可以将其从async void转换为async Task? -
@TheodorZoulias,是的,有可能
-
如果您有办法管理并最终
await这些任务,我可能值得切换到async Task。否则,如果您想以一种即发即弃的方式启动这些任务,则最好坚持使用async void。至少在出现错误的情况下,应用程序会崩溃而不是挂起。
标签: c# .net async-await task