[英]Parent Task ignores Child Tasks
在下面的代码中,我期望结果为3
Task<int> parent = Task.Factory.StartNew(() =>
{
var sum = 0;
TaskFactory tf = new TaskFactory(TaskCreationOptions.AttachedToParent,
TaskContinuationOptions.ExecuteSynchronously);
tf.StartNew(() => sum++);
tf.StartNew(() => sum++);
tf.StartNew(() => sum++);
return sum;
});
var finalTask = parent.ContinueWith(parentTask => Console.WriteLine(parentTask.Result));
finalTask.Wait();
但是结果是0,我不明白。 奇怪的是,当我将其更改为使用和Array时,它似乎的确做了正确的事情。
Task<Int32[]> parent = Task.Factory.StartNew(() =>
{
var results = new Int32[3];
TaskFactory tf = new TaskFactory(TaskCreationOptions.AttachedToParent,
TaskContinuationOptions.ExecuteSynchronously);
tf.StartNew(() => results[0] = 0);
tf.StartNew(() => results[1] = 1);
tf.StartNew(() => results[2] = 2);
return results;
});
var finalTask = parent.ContinueWith(
parentTask =>
{
foreach (int i in parentTask.Result)
Console.WriteLine(i);
});
finalTask.Wait();
这里的结果是预期的:0 1 2
我想我遗漏了一些非常明显的东西,我需要在第一段代码中解决什么才能使其返回3
更新我已经查看了此解决方案 ,这就是为什么我没有使用Task.Run的原因,但并没有真正的改变
值类型与引用类型语义上的差异导致的案例之间的差异。 int
是一种值类型,因此在返回时将其复制,并且不会看到对sum
变量的任何后续更改。 数组是引用类型,因此只能在返回时复制引用,因此子任务在数组中所做的任何更改都是可见的,因为它是同一数组。 为了使第一种情况起作用,您需要将int
替换为某些引用类型:
public class Reference<T> {
public T Value;
public Reference(T value) {
Value=value;
}
}
public static void Test() {
Task<Reference<int>> parent=Task.Factory.StartNew(() => {
var sum=new Reference<int>(0);
TaskFactory tf=new TaskFactory(TaskCreationOptions.AttachedToParent,
TaskContinuationOptions.ExecuteSynchronously);
tf.StartNew(() => sum.Value++);
tf.StartNew(() => sum.Value++);
tf.StartNew(() => sum.Value++);
return sum;
});
var finalTask=parent.ContinueWith(parentTask => Console.WriteLine(parentTask.Result.Value));
finalTask.Wait();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.