gpt4 book ai didi

c# - C# 考试 70-483 引用书的例子有错吗? (父/子线程)

转载 作者:行者123 更新时间:2023-11-30 12:38:30 26 4
gpt4 key购买 nike

在第一版C# 70-483 Exam Ref , 示例 1-12 给出了将子任务附加到父任务的示例。我认为这是错误的,并希望有人在继续这个假设之前检查我的理解。示例中的代码如下:

using System;
using System.Threading.Tasks;

namespace Chapter1
{
public static class Program
{
public static void Main()
{
Task<Int32[]> parent = Task.Run(() =>
{
var results = new Int32[3];

new Task(() => results[0] = 0, TaskCreationOptions.AttachedToParent).Start();
new Task(() => results[1] = 1, TaskCreationOptions.AttachedToParent).Start();
new Task(() => results[2] = 2, TaskCreationOptions.AttachedToParent).Start();

return results;
});


var finalTask = parent.ContinueWith(parentTask =>
{
foreach (var i in parentTask.Result)
{
Console.WriteLine(i);
}
});

finalTask.Wait();
}

}
}

问题出在 Task.Run 上。 MSDN explains不允许允许附加子任务。在本书出版时(2013 年),我认为这可能是 .NET 版本的问题,但 MSDN 文章是在本书出版前两年发布的。

这特别棘手,因为如果执行上面的代码,results 数组确实将其值设置为 0、1 和 2。但是,如果lambda 做任何比这更耗时的事情,数组中的那个索引没有设置值。

例如,下面的代码将“一”和“二”分别分配给results元素1和2,但元素0为空。

using System;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Chapter1
{
public static class Program
{
public static void Main()
{
Task<String[]> parent = Task.Run(() =>
{
var results = new String[3];

new Task(() => {
SHA256 mySHA256 = SHA256.Create();
byte[] messageBytes = Encoding.ASCII.GetBytes("asdf");
byte[] hashBytes = mySHA256.ComputeHash(messageBytes);
results[0] = BitConverter.ToString(hashBytes).Replace("-", "");
}, TaskCreationOptions.AttachedToParent).Start();

new Task(() => results[1] = "one", TaskCreationOptions.AttachedToParent).Start();
new Task(() => results[2] = "two", TaskCreationOptions.AttachedToParent).Start();

return results;
});


var finalTask = parent.ContinueWith(parentTask =>
{
foreach (var i in parentTask.Result)
{
Console.WriteLine(i);
}
});

finalTask.Wait();
}

}
}

当我使用任务工厂(示例中未显示)启动父任务时,一切都按预期工作,TaskCreationOptions 影响子线程的同步。

所以我的问题是:

  1. 我的理解是否正确,将 TaskCreationOptions.AttachedToParent 传递给在 Thread.Run 下创建的子任务是没有意义的?
  2. 我的假设是否正确,即本书的示例之所以有效,是因为子任务 lambda 只是执行恰好在父线程终止之前完成的分配?

最佳答案

我相信您的两个问题(断言)都是正确的。 This MSDN文章似乎涵盖得很好。

Re 2,正如文章所说,将 AttachedToParent 传递给以 Task.Run() 开始的任务会产生“不可预测”的结果,其中之一就是你观察。

我应该添加一个细微差别,即“子”任务将在 ContinueWith() 开始后继续运行,因此它们在相应的时间之前获得(一点点)额外时间来完成Console.WriteLine()

关于c# - C# 考试 70-483 引用书的例子有错吗? (父/子线程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51812708/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com