有没有办法查看一个任务是否已经有了后续任务?

5

有没有办法找出一个任务是否已经有了续集?我想要给一个已存在的任务添加续集,但只有当该任务还没有续集时才添加,就像这样:

void RequestUpdate()
{
    if (_updateTask.IsCompleted)
    {
        _updateTask = TakeASnapshotOfTheCurrentStateAndUpdateAsync();
    }
    else 
    {
        if (_updateTask.HasNoContinuation){ // how do I check for this?
            _updateTask.ContinueWith(() => RequestUpdate())
        }
    }
}

还有没有更好的方法来编写这种逻辑呢?


创建一个新的任务,使用 await _updateTask 并调用 RequestUpdate -- 确保只执行一次,通过跟踪该任务完成。这里不适合使用 Continuations。 - Jeroen Mostert
4
那里有一个恶劣的竞态条件 - 在你检查它之后,_updateTask.IsCompleted 可能会立即变为 true,在执行 else 之前。此外,在使用 ContinueWith() 后,您需要将任务变量分配给返回值,例如 _updateTask = _updateTask.ContinueWith(() => RequestUpdate()) - Matthew Watson
这只是一种非常复杂的方式,以紧密循环的方式不断调用TakeASnapshotOfTheCurrentStateAndUpdateAsync吗? - Fildor
@Fildor 不,我的意图是如果在任务运行时调用了RequestUpdate,则应在TakeASnapshotOfTheCurrentStateAndUpdateAsync结束时再次调用它。否则,TakeASnapshotOfTheCurrentStateAndUpdateAsync应该只是终止而没有任何后续操作。 - John Smith
那么,这个怎么样:https://dotnetfiddle.net/o5iC4M? - Fildor
1个回答

7

从技术上讲,我们可以借助反射来打破Task类的私有事务,并实现类似以下内容的功能:

using System.Reflection;

...

private static bool HasContinuation(Task task) {
  if (task is null)
    return false;

  var result = typeof(Task)
    .GetField("m_continuationObject", BindingFlags.NonPublic | BindingFlags.Instance)
   ?.GetValue(task);

  return result is not null && result?.GetType() != typeof(object);
}

然而,上述代码只是一个快速(且不太规范)的补丁;不能保证未来版本的 .net 将使用 m_continuationObject 字段。


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