Bra*_*non 5 .net c# multithreading task-parallel-library
我有一些方法.我们称之为"TurnOn"和"TurnOff".每个都返回一个未启动的任务(如在System.Threading.Tasks.Task中).一旦启动,该任务大约需要一秒钟才能完成.我有一些代码与Task.ContinueWith方法(示出排队这些这里).问题是我只想要当前正在运行的任务(如果有的话)加上最近请求的任务来运行.目前,如果我的用户在一秒内切换开/关开关十次,我的代码需要花费二十秒来赶上.这只是我关心的最终要求.我怎样才能做到这一点?我无法在ContinueWith方法中看到一种方法来知道它之后是否还有另一个ContinueWith方法.我一直在看这里的例子,但不太清楚如何应用它.
更新:现在可以在库中找到它:https://github.com/BrannonKing/Kts.ActorsLite.它被命名为"MostRecent ......"
只需创建一个类来跟踪当前正在执行的任务、接下来要运行的操作,并在上一个操作完成时运行“下一个”操作。这里的关键是,如果当您将新操作放入队列时下一个操作具有值,您可以简单地替换nextTask而不是添加另一个延续。
public class TaskQueue
{
private Task currentlyExecuting = Task.FromResult(false);
public Task continuation = null;
private CancellationTokenSource cts = new CancellationTokenSource();
private Action nextTask = null;
private object key = new object();
public Task Queue(Action action)
{
lock (key)
{
if (nextTask == null)
{
nextTask = action;
ScheduleContinuation();
return continuation;
}
else
{
cts.Cancel();
nextTask = action;
ScheduleContinuation();
return continuation;
}
}
}
private void ScheduleContinuation()
{
cts = new CancellationTokenSource();
var token = cts.Token;
continuation = currentlyExecuting.ContinueWith(t =>
{
lock (key)
{
currentlyExecuting = Task.Run(nextTask);
token.ThrowIfCancellationRequested();
nextTask = null;
}
}, cts.Token);
}
}
Run Code Online (Sandbox Code Playgroud)
虽然您可以在这里接受未启动的任务,并且这样做是一个非常简单的重写,但我认为最好在这里接受委托并创建任务,然后在准备好启动时启动任务。