gpt4 book ai didi

.net - 任务结果评估的时间安排

转载 作者:行者123 更新时间:2023-12-03 13:16:04 26 4
gpt4 key购买 nike

这是一个“学术性”问题,而不是一个以官方身份影响我目前正在从事的工作的问题,但是我认为这里有人可以向我解释这一问题。

我在LinqPAD中玩CancellationToken(我提到了这个细节,所以不熟悉它的人知道Dump()基本上是Console.WriteLine()的简写),并且我正在尝试一种情况,在我的任务完成时,我的主线程处于 sleep 状态。这是在运行几种取消任务的变体之后完成的,然后才能完成它的IsCanceled属性播放,并验证取消时Result属性是否不可访问。这是我的虚拟LinqPAD程序的样子:

void Main()
{
var cts = new CancellationTokenSource();
var task = Task.Factory.StartNew(() => Test())
.ContinueWith(t => t.Result, cts.Token)
.ContinueWith(t =>
{
if (t.IsCanceled)
{
"Cancelled".Dump();
}
else if (t.IsCompleted)
{
"Completed".Dump();
t.Result.Sum (r => r).Dump();
}
});
//sleep long enough to make sure the Task completes
Thread.Sleep(6000);
}

private IEnumerable<int> Test()
{
foreach(var i in Enumerable.Range(0, 10))
{
yield return i;
Task.Delay(500).Wait();
}
}

这的行为-主要是-我的期望:输出是“已完成”,后跟“45”。我没想到的是,直到Thread.Sleep()调用完成,才输出“45”,但是立即输出了“Completed”。

所以我的问题是:如何立即评估任务的 IsCompleted标志,但是直到调用线程从 Result调用返回后才评估 Thread.Sleep()属性?另外,有什么办法可以重组此结构,使其要么立即输出,要么都等待 Sleep()调用的结束?

我知道这个例子是人为的,但是我不能为这种人为的行为而烦恼。
编辑
另一个问题:这种观察到的行为是否表示我可以进入一种状态,即在评估 Result时与何时能够评估 IsCompleted之间,任务的 Result属性发生变化?
编辑2
经过进一步的研究,我能够回答自己的问题之一:通过更改 Thread.Sleep()的行为以返回方法中建立的IList <>,我可以强制“Completed”输出等到 Test()完成之后而不是 yield return的IEnumerable。我了解IEnumerable的一般工作原理,但是通过介绍任务在这里看到的行为却使我无法接受。

最佳答案

那是因为'yield return'和IEnumerable <>的工作方式。

因此,当您调用Test()时,它实际上并没有运行循环,而是仅返回IEnumerable <>。

为了证明您可以运行此代码-

    var stopwatch = Stopwatch.StartNew();
var results = Test();


Console.WriteLine("Time after running Test {0}", stopwatch.ElapsedMilliseconds);

foreach (var result in results)
{
Console.WriteLine("Looping {0}", stopwatch.ElapsedMilliseconds);
}

所以只有在这行代码之后
t.Result.Sum(r => r).Dump();
您开始循环并等待Task.Delay(500).Wait();。
完成后将汇总数字并将其写入控制台。

关于.net - 任务结果评估的时间安排,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20764871/

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