我正在尝试为Action创建一个方便的扩展方法,以便在延迟后运行该操作:
public static void DelayAction(this Action DelayedAction, int millisecondDelay, CancellationToken Token)
{
Task t = Task.Factory.StartNew(() => { Thread.Sleep(millisecondDelay); }, Token, TaskCreationOptions.None, TaskScheduler.Default);
t.ContinueWith(_ => DelayedAction, Token, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}我调用了一个函数,该函数使用这些扩展
private void DelayTask(Action ActiontoDelay, int millisecondDelay)
{
ActiontoDelay.DelayAction(millisecondDelay, _TokenSource.Token);
} 我这样称呼它:
DelayTask(() => { _SomeFunction(SomeArgs); }, 1500);但这一切似乎都落在了一个整体上,动作永远不会触发。我哪里错了?
编辑17:11-11:00:
我删除了泛型扩展方法,因为它与本例无关。
我还在这里发表了评论,因为它没有在评论中清楚地格式化代码
如果不是调用
DelayTask(() => { _SomeFunction(SomeArgs); }, 1500); 我直接这样做:
Task t = Task.Factory.StartNew(() => { Thread.Sleep(1500); }, Token, TaskCreationOptions.None, TaskScheduler.Default);
t.ContinueWith(() => { _SomeFunction(SomeArgs); }, Token, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); 它工作得很好(抱歉,如果有任何语法错误,我已经根据记忆完成了),所以我认为我的问题在于对Nick Butler的答案所回避的Action的处理
发布于 2011-10-18 01:36:05
您的延续将返回DelayedAction委托,而不是调用它:
t.ContinueWith(_ => DelayedAction(), Token, ...发布于 2011-10-18 01:16:54
如果任务不是一个很强的需求,我建议使用System.Threading.Timer,它有内置的“延迟”功能,构造函数看起来像这样:
public Timer(
TimerCallback callback,
Object state,
int dueTime,
int period
)MSDN
dueTime类型: System.Int32调用回调前的延迟时间,单位为毫秒。指定Timeout.Infinite以阻止计时器启动。指定零(0)可立即启动计时器。
!同样重要的是,您可以在构建阶段之后更改此延迟。
public static void DelayAction<T>(
this Action<T> delayedAction,
T argument,
int millisecondDelay,
CancellationToken cancellationToken)
{
// Timeout.Infinite to disable periodic signaling.
var timer = new System.Threading.Timer(x =>
{
cancellationToken.ThrowIfCancellationRequested();
delayedAction.Invoke(argument);
},
null,
millisecondDelay,
Timeout.Infinite);
} 发布于 2011-10-18 03:34:17
当然,你也可以通过任务来实现。问题是,您调用了TaskFactory的StartNew,它会立即启动您的任务。
试着这样做--这应该行得通:
public static void DelayAction<T>(this Action<T> DelayedAction, int millisecondDelay, CancellationToken Token)
{
var task = new Task(t => { Thread.Sleep(millisecondDelay); }, null, Token);
task.ContinueWith(t => DelayedAction, Token, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
task.Start();
} https://stackoverflow.com/questions/7797001
复制相似问题