是否可以使用单一 TPL 方法在 A 和 B 运行完成后继续执行任务 C,而不会出现错误或取消?

发布于 2024-10-06 16:32:10 字数 804 浏览 0 评论 0原文

我现在已经尝试使用 Task.Factory.ContinueWhenAll() 几次,目的是仅当所有前提都运行完成且没有任何错误或取消时才调用延续。这样做会导致 ArgumentOutOfRangeException 与消息一起抛出,

排除多个任务的延续的特定延续类型是无效的。参数名称:continuationOptions

例如,

var first = Task.Factory.StartNew<MyResult>(
    DoSomething,
    firstInfo,
    tokenSource.Token);
var second = Task.Factory.StartNew<MyResult>(
    DoSomethingElse,
    mystate,
    tokenSource.Token);
var third = Task.Factory.ContinueWhenAll(
    new[] { first, second },
    DoSomethingNowThatFirstAndSecondAreDone,
    tokenSource.Token,
    TaskContinuationOptions.OnlyOnRanToCompletion, // not allowed!
    TaskScheduler.FromCurrentSynchronizationContext());

TPL 不接受该代码。有没有办法使用其他 TPL 方法来做类似的事情?

I've tried to use Task.Factory.ContinueWhenAll() a few times now with the intent of invoking a continuation only when all the antecedents run to completion without any errors or cancellations. Doing so causes an ArgumentOutOfRangeException to be thrown with the message,

It is invalid to exclude specific continuation kinds for continuations off of multiple tasks. Parameter name: continuationOptions

For example, the code

var first = Task.Factory.StartNew<MyResult>(
    DoSomething,
    firstInfo,
    tokenSource.Token);
var second = Task.Factory.StartNew<MyResult>(
    DoSomethingElse,
    mystate,
    tokenSource.Token);
var third = Task.Factory.ContinueWhenAll(
    new[] { first, second },
    DoSomethingNowThatFirstAndSecondAreDone,
    tokenSource.Token,
    TaskContinuationOptions.OnlyOnRanToCompletion, // not allowed!
    TaskScheduler.FromCurrentSynchronizationContext());

is not acceptable to the TPL. Is there a way to do something like this using some other TPL method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

春风十里 2024-10-13 16:32:10

似乎没有直接的方法可以做到这一点。我通过将 OnlyOnRanToCompletion 更改为 None 并检查传递到延续的每个任务的 Exception 是否为非空来解决这个问题。类似的方法

private void DoSomethingNowThatFirstAndSecondAreDone(Task<MyResult>[] requestTasks)
{
    if (requestTasks.Any(t => t.Exception != null))
        return;

    // otherwise proceed...
}

可行,但这似乎不是一种非常令人满意的方法来处理具有多个先行条件的情况,并且打破了单例 Task.Factory.ContinueWith 使用的模式。

There doesn't appear to be a direct way to do this. I've gotten around this by changing OnlyOnRanToCompletion to None and checking to see if Exception is non-null for each task passed into the continuation. Something like

private void DoSomethingNowThatFirstAndSecondAreDone(Task<MyResult>[] requestTasks)
{
    if (requestTasks.Any(t => t.Exception != null))
        return;

    // otherwise proceed...
}

works, but this doesn't seem to be a very satisfying way to handle the case with multiple antecedents and breaks with the pattern the single-case Task.Factory.ContinueWith uses.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文