Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#考试70-483参考书示例错误吗?(父/子线程)_C#_.net_Task - Fatal编程技术网

C#考试70-483参考书示例错误吗?(父/子线程)

C#考试70-483参考书示例错误吗?(父/子线程),c#,.net,task,C#,.net,Task,在第一版中,示例1-12给出了将子任务附加到父任务的示例。我认为这是一个错误,希望有人在继续这个假设之前检查我的理解。示例中的代码如下所示: 使用系统; 使用System.Threading.Tasks; 名称空间第1章 { 公共静态类程序 { 公共静态void Main() { 任务父级=任务。运行(()=> { var结果=新的Int32[3]; 新任务(()=>结果[0]=0,TaskCreationOptions.AttachedToParent.Start(); 新任务(()=>res

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

使用系统;
使用System.Threading.Tasks;
名称空间第1章
{
公共静态类程序
{
公共静态void Main()
{
任务父级=任务。运行(()=>
{
var结果=新的Int32[3];
新任务(()=>结果[0]=0,TaskCreationOptions.AttachedToParent.Start();
新任务(()=>results[1]=1,TaskCreationOptions.AttachedToParent.Start();
新任务(()=>results[2]=2,TaskCreationOptions.AttachedToParent.Start();
返回结果;
});
var finalTask=parent.ContinueWith(parentTask=>
{
foreach(parentTask.Result中的变量i)
{
控制台写入线(i);
}
});
finalTask.Wait();
}
}
}
问题在于
任务。运行
。这不允许附加子任务。我认为这可能是出版(2013年)时.NET版本的一个问题,但MSDN文章是在该书出版前两年发表的

这尤其棘手,因为如果执行上面的代码,
results
数组确实会将其值设置为0、1和2。但是,如果lambda执行比此更耗时的操作,则在数组中的该索引处不会设置任何值

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

使用系统;
使用System.Security.Cryptography;
使用系统文本;
使用System.Threading.Tasks;
名称空间第1章
{
公共静态类程序
{
公共静态void Main()
{
任务父级=任务。运行(()=>
{
var结果=新字符串[3];
新任务(()=>{
SHA256 mySHA256=SHA256.Create();
byte[]messageBytes=Encoding.ASCII.GetBytes(“asdf”);
byte[]hashBytes=mySHA256.ComputeHash(messageBytes);
结果[0]=位转换器.ToString(hashBytes).Replace(“-”,”);
},TaskCreationOptions.AttachedToParent.Start();
新任务(()=>results[1]=“one”,TaskCreationOptions.AttachedToParent.Start();
新任务(()=>results[2]=“two”,TaskCreationOptions.AttachedToParent.Start();
返回结果;
});
var finalTask=parent.ContinueWith(parentTask=>
{
foreach(parentTask.Result中的变量i)
{
控制台写入线(i);
}
});
finalTask.Wait();
}
}
}
当我使用任务工厂(示例中未显示)启动父任务时,一切都按预期工作,
TaskCreationOptions
会影响子线程的同步

因此,我的问题是:

  • 我的理解正确吗?将
    TaskCreationOptions.AttachedToParent
    传递到在
    线程下创建的子任务中是没有意义的。Run
  • 我的假设正确吗?本书的示例之所以有效,是因为子任务lambda只是执行在父线程终止之前完成的任务

  • 我相信你的两个问题(断言)都是正确的。这篇文章似乎涵盖得很好

    Re2,正如文章所说,将
    AttachedToParent
    传递给以
    task.Run()
    开始的任务会产生“不可预测”的结果,其中一个结果就是您观察到的结果


    我应该添加一个细微差别,那就是“子”任务将在
    ContinueWith()开始之后继续运行,因此它们在相应的
    控制台之前有(一点点)额外的时间来完成。WriteLine()

    “unexpective”很好地总结了一个经典的竞争条件在那篇文章中,有由于task.Run重载的默认任务创建选项包括TaskCreationOptions.Denychildatach,因此此示例在功能上与“分离的子任务”部分中的第一个示例等效。“这可能表明,
    denychildatach
    只是默认值,可以更改。”。。有趣的是……当然没有过载,因为这需要
    TaskCreationOptions
    ,所以“默认”实际上是强制的,不可配置的,好吧,这就是答案!