C# 访问Task.ContinueWith中的值
我正在使用以下代码启动任务:C# 访问Task.ContinueWith中的值,c#,task-parallel-library,C#,Task Parallel Library,我正在使用以下代码启动任务: var token = tokenSource.Token; var taskWithToken = new Task(() => new ProcessMyCommand(_unitOfWork, ..., batchRunId, token).Execute(), token); 在我的继续中,我需要知道batchRunId和…中列出的一些其他变量,但是,这不可能吗 taskWithToken.ContinueWith(
var token = tokenSource.Token;
var taskWithToken = new Task(() =>
new ProcessMyCommand(_unitOfWork, ..., batchRunId, token).Execute(),
token);
在我的继续中,我需要知道batchRunId和…
中列出的一些其他变量,但是,这不可能吗
taskWithToken.ContinueWith(task =>
{
if (!task.IsCanceled)
return;
//TODO: make sure no more subsequent runs happen
//TODO: sync with source data
}
);
我有什么遗漏吗?如何确保
.ContinueWith
执行时能够访问所需的值?您可以创建MyTaskData
类来存储数据和结果,还可以存储MyTaskData PreviousTaskData
属性(来自上一个任务)创建结果链接列表。创建一个任务
,在该任务中,最后返回myNewTaskData代码>。然后,ContinueWith(…)
在其中可以通过Task.Result
属性获得以前的结果。
对于已取消的任务的继续
ContinueWith
有一个带有TaskContinuationOptions
参数()在可以指定notinconceled
的地方,可以创建MyTaskData
类来存储数据和结果,还可以存储MyTaskData PreviousTaskData
属性(来自上一个任务)创建结果链接列表。创建一个任务
,在该任务中,最后返回myNewTaskData代码>。然后,ContinueWith(…)
在其中可以通过Task.Result
属性获得以前的结果。
至于取消的任务的继续
ContinueWith
有一个带有TaskContinuationOptions
参数()的变量,您可以首先指定notincanceled
,我甚至不确定您的情况下是否需要继续。您的代码可以简化为以下内容:
var taskWithToken = new Task(() =>
{
new ProcessMyCommand(_unitOfWork, ..., batchRunId, token).Execute();
// code from the continuation here
},
token);
但是如果您确实想使用ContinueWith()
,并且由于ReSharper警告而担心使用它,那么您不必这样做。大多数情况下,像这样的代码非常好,您可以忽略警告
更长的版本:当您编写一个lambda引用封闭范围(所谓)中的内容时,编译器必须为此生成代码。它究竟如何做到这一点是一个实现细节,但当前编译器为单个方法中的所有闭包生成一个闭包类
在您的例子中,这意味着编译器生成了一个类,其中包含局部变量this
(因为\u unitOfWork
)、请求和批处理运行ID
(可能还有您没有显示的其他变量)。此关闭对象在新任务
lambda和ContinueWith()lambda之间共享,即使第二个lambda不使用请求
或此
。只要第二个lambda是从某处引用的,这些对象就不能被垃圾收集,即使不能从中访问它们
所以,这种情况可能会导致内存泄漏,我相信这就是为什么ReSharper会警告您。但在几乎所有情况下,该内存泄漏要么不存在(因为第二个lambda的引用时间不比第一个长),要么非常小。因此,在大多数情况下,您可以安全地忽略该警告。但是,如果您发现神秘的内存泄漏,您应该调查您使用lambdas的方式,尤其是您收到此警告的地方。首先,我甚至不确定您的情况是否需要继续。您的代码可以简化为以下内容:
var taskWithToken = new Task(() =>
{
new ProcessMyCommand(_unitOfWork, ..., batchRunId, token).Execute();
// code from the continuation here
},
token);
但是如果您确实想使用ContinueWith()
,并且由于ReSharper警告而担心使用它,那么您不必这样做。大多数情况下,像这样的代码非常好,您可以忽略警告
更长的版本:当您编写一个lambda引用封闭范围(所谓)中的内容时,编译器必须为此生成代码。它究竟如何做到这一点是一个实现细节,但当前编译器为单个方法中的所有闭包生成一个闭包类
在您的例子中,这意味着编译器生成了一个类,其中包含局部变量this
(因为\u unitOfWork
)、请求和批处理运行ID
(可能还有您没有显示的其他变量)。此关闭对象在新任务
lambda和ContinueWith()lambda之间共享,即使第二个lambda不使用请求
或此
。只要第二个lambda是从某处引用的,这些对象就不能被垃圾收集,即使不能从中访问它们
所以,这种情况可能会导致内存泄漏,我相信这就是为什么ReSharper会警告您。但在几乎所有情况下,该内存泄漏要么不存在(因为第二个lambda的引用时间不比第一个长),要么非常小。因此,在大多数情况下,您可以安全地忽略该警告。但是如果您发现神秘的内存泄漏,您应该调查您使用lambdas的方式,尤其是在您收到此警告的地方。而不是取消检查,只需将相同的令牌传递给延续。接下来,是否有一个原因使continuation不能关闭变量?结果将在一个属性中:task.result
@Romoku,但他不仅需要结果,还需要传递给该函数的参数。为什么这些参数不可访问?您是从不同的作用域调用ContinueWith()
吗?@RaySaltrelli我收到一个R#警告“隐式捕获闭包:请求,此”,因此似乎有问题。与其取消检查,不如将相同的令牌也传递给continuation。接下来,是否有一个原因使continuation不能关闭变量?结果将在一个属性中:task.result
@Romoku,但他不仅需要结果,还需要传递给tha的参数