3

我正在尝试使用 .NET Task 框架。我的场景是这样的:每当我的类上的任何属性发生变化时,我都有一个需要执行的任务。如果它已经在执行,任务应该立即退出并重新启动,这样在任何给定时间只有一个任务在运行。实际上,停止任务可能需要一秒钟,在此期间我可能会收到多个 PropertyChanged 事件(这应该只会触发任务的一次重新运行)。而且我的 PropertyChanged 处理程序无法阻止。

在这种情况下,我似乎需要一个 volatile 标志来退出前一个任务。但是,我不知道在哪里等待它退出。同时,我不认为我可以在事物未运行时添加 ContinueWith 方法。(而且我不想嵌套 ContinueWith 多个级别,对吗?)

任务库中对我有什么帮助吗?对于这一层级深的任务队列,您还有哪些其他建议?我正在使用.NET 4.5。

4

2 回答 2

1

所以我想为此编写一个TaskScheduler,但该接口没有提供一种机制来确保所有任务都有一个取消令牌并能够取消已经运行的任务,所以我们必须使用一个调度程序来完成不遵循提供的 TPL 模型/接口。

当安排第一个任务时取消前一个任务(如果没有前一个任务或者它已经完成,它将不会做任何事情)。接下来,它将当前任务设置为直到前一个任务结束才开始的任务,并在其主体中运行给定的操作。需要Alock以便如果有两个调用Schedule一个将立即取消另一个,并且未取消的版本将是分配给 的那个current

public class SingleThreadedKillPredecssorScheduler
{
    private Task current = Task.FromResult(true);
    private CancellationTokenSource cts = new CancellationTokenSource();
    private object key = new object();

    public Task Schedule(Action<CancellationToken> action)
    {
        lock (key)
        {
            cts.Cancel();
            cts = new CancellationTokenSource();
            current = current.ContinueWith(t => action(cts.Token), cts.Token);
            return current;
        }
    }
    public Task<T> Schedule<T>(Func<CancellationToken, T> function)
    {
        lock (key)
        {
            cts.Cancel();
            cts = new CancellationTokenSource();
            var next = current.ContinueWith(t => function(cts.Token), cts.Token);
            current = next;
            return next;
        }
    }
}
于 2013-07-11T21:13:37.013 回答
0

我能想到的最简单的方法是在任务开始时锁定某个对象,并在任务执行期间保持锁定。这样一个新的任务将开始,但在前一个任务完成之前不会做任何事情。

另外,我不认为有办法停止任务,其他通知它并在任务中检查是否存在此类通知并退出任务。您可以使用 CancellationToken,或者如果 case 很简单,甚至可以只使用 bool,我会在这种情况下使用它。

于 2013-07-11T21:00:23.343 回答