gpt4 book ai didi

c# - 取消异步操作

转载 作者:行者123 更新时间:2023-12-04 00:32:58 28 4
gpt4 key购买 nike

private async void TriggerWeekChanged(Week currentWeek)
{
await LoadDataForSelectedWeek(currentWeek); //Split into multiple methods
}

如果用户敲击 Change_Week 按钮,我该如何取消当前任务,并使用新参数启动新任务?

我试过这样的:

private async Task Refresh(Week selectedWeek, CancellationToken token)
{
Collection.Clear();

await LoadDataFromDatabase();

token.ThrowIfCancellationRequested();

await ApplyDataToBindings();

token.ThrowIfCancellationRequested();

//Do some other stuff
}

问题是:在我的 Collection 中,当我连续点击按钮禁食时,我获得了数周的数据。

最佳答案

等待的一切都需要在 CancellationToken 上可见。如果它是您编写的自定义 Task,它应该接受它作为参数,并定期在函数内检查它是否已被取消。如果是这样,它应该采取任何必要的行动(如果有的话)来停止或回滚正在进行的操作,然后调用 ThrowIfCancellationRequested()

在您的示例代码中,您可能还想将token 传递给LoadDataFromDatabaseApplyDataToBindings作为这些任务的任何子任务。

可能有一些更高级的情况,您不想将相同 CancellationToken 传递给子任务,但您仍然希望它们是可取消的。在这些情况下,您应该在 Task 内部创建一个新的 Cancellationtoken 用于子任务。

要记住的重要一点是,ThrowIfCancellationRequested 标记了 Task 中可以停止 Task 的安全位置。没有保证运行时自动检测安全位置的安全方法。如果 Task 在请求取消后立即自动取消其自身,则它可能会处于未知状态,因此由开发人员标记这些安全位置。在整个 Task 中多次调用检查取消的情况并不少见。


我刚刚注意到您的 TriggerWeekChanged 函数是 async void。当它用于不是事件处理程序的东西时,通常被认为是反模式。在跟踪方法内 async 操作的完成状态以及处理可能从其中抛出的任何异常时,它可能会导致很多问题。您应该非常厌倦任何标记为 async void 的非事件处理程序,因为 99% 或更多的做法都是错误的时间。我强烈建议将其更改为 async Task,并考虑从您的其他代码中传入 CancellationToken

关于c# - 取消异步操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46116290/

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