Do not apply extension method

I am trying to create a convenient extension method for Action to basically start this action after a delay: while my extension looks like this:

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()); } 

I have a function that I call, which in turn uses these extensions

  private void DelayTask(Action ActiontoDelay, int millisecondDelay) { ActiontoDelay.DelayAction(millisecondDelay, _TokenSource.Token); } 

What I call so:

  DelayTask(() => { _SomeFunction(SomeArgs); }, 1500); 

But all this seems to throw the whole, and the action never works. Where am I mistaken?

Edit 17-11-11 2300 hours:

I removed the general extension method, since it is not relevant to this example.

Also posting a comment here, as it does not format the code explicitly in the comments

If instead of calling

 DelayTask(() => { _SomeFunction(SomeArgs); }, 1500); 

I do it directly:

 Task t = Task.Factory.StartNew(() => { Thread.Sleep(1500); }, Token, TaskCreationOptions.None, TaskScheduler.Default); t.ContinueWith(() => { _SomeFunction(SomeArgs); }, Token, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); 

It works fine (sorry if there is any syntax error there, I made it from memory). Therefore, I believe that my problem is with handling the action, which Nick Butler Answer shies away from

+4
source share
3 answers

Your continuations are returned by the DelayedAction delegate without calling it:

 t.ContinueWith(_ => DelayedAction(), Token, ... 
+5
source

If Tasks is not a strong requirement, I would suggest using System.Threading.Timer , which has a built-in delay function, the constructor looks like this:

 public Timer( TimerCallback callback, Object state, int dueTime, int period ) 

MSDN :

dueTime Type: System.Int32 The number of delays before the callback is called in milliseconds. Specify the wait time. prohibit the start of the timer. Specify zero (0) to start the timer immediately.

! It is also important to change this delay after the construction phase.


 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); } 
+3
source

Of course, you can do this with assignments. The problem was that you called StartNew of TaskFactory, which immediately starts your task.

Try it this way: this should work:

 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(); } 
0
source

All Articles