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

C#考试70-483参考书的例子有错吗? (父子线程),第1张

概述在 C# 70-483 Exam Ref的第一版中,示例1-12给出了将子任务附加到父任务的示例.我认为这是错误的,并希望有人在继续这个假设之前检查我的理解.示例中的代码如下: using System;using System.Threading.Tasks;namespace Chapter1{ public static class Program { 在 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这不允许附加子任务.我认为这可能是.NET版本在发布时(2013年)的一个问题,但MSDN文章是在本书出版前两年发布的.

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

例如,下面的代码分别将“one”和“two”分配给结果元素1和2,但元素0为null.

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影响子线程的同步.

所以我的问题是:

>我的理解是正确的,将TaskCreationoptions.Attachedtoparent传递给在Thread.Run下创建的子任务是没有意义的吗?
>我的假设是否正确,本书的示例仅有效,因为子任务lambdas只是执行在父线程终止之前完成的赋值?

解决方法 我相信你的问题(断言)都是正确的. This MSDN文章似乎很好地涵盖了它.

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

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

总结

以上是内存溢出为你收集整理的C#考试70-483参考书例子有错吗? (父/子线程)全部内容,希望文章能够帮你解决C#考试70-483参考书的例子有错吗? (父/子线程)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1233182.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存