任务完成前,Will Task.WhenAny会注销未完成任务的继续执行吗?

4
考虑一个具有某种生命周期的类。在此期间,事件可能会发生任意次数,并且通过完成任务(在事件后更新)来发出信号。该对象也可以关闭,结束其生命周期。关机也是通过完成任务来发出信号的。它也可以永远存在。
现在考虑一些异步工作流模拟对象的生命周期:
//will be completed on Shutdown. Is the same object for the entire lifetime.
Task shutdownTask = ... 

while(true)
{
    //will be completed when the event occurs. Is different on each loop.
    Task eventTask = ... 

    if (await Task.WhenAny(shutdownTask, eventTask) == eventTask)
    {
        //Event has occured
        ...
    }
    else
    {
        //Object has been shutdown. React and leave.
        ...
        return;
    }
}

一个 eventTask 的例子可以是异步地从 async Queue 中出列对象。

直觉上,我对这种方式来建模对象的生命周期没有任何问题。然而,这个对象可能会永远存在,且在 shutdownTask 上注册了无数的连续任务。或者它们并不是无限的吗?连续任务会被取消注册还是应用程序最终会崩溃?是否有一种更清晰的模式来建模这样的控制流程呢?


任务完成后,您要添加更多的继续吗?在任务完成后“添加”继续只会立即同步执行委托。 - Peter Ritchie
在我的代码示例中,我没有向已完成的任务添加continuations。即使是Task.WhenAny也不会这样做。 - Daniel C. Weber
是的,一旦任何一个任务完成,所有其他任务中的继续操作都将被删除。在您的示例中,如果eventTask完成,那么该继续操作将从shutdownTask中删除。 - Peter Ritchie
1个回答

3

是的,当其中任何一个任务被触发时,所有给定任务中的续订将被移除。


取消一个 continuation 不是做了同样的事情吗? - svick
这方面有官方文档吗?我刚查看了 Mono 源代码,似乎没有找到所需的属性。我在原始问题中添加了“mono”标签。 - Daniel C. Weber
这是.NET的WhenAny的未记录实现细节。在ILSpy中打开它。我猜Mono技术上不需要复制未记录的行为,但如果你报告了这个问题,他们可能会认为这是一个有效的错误。 - Cory Nelson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接