Reputation: 3817
I have this code that creates a task:
Task.Factory.StartNew(() =>
{
ExtractStuff(fileName);
});
Sometimes I need to pause for few seconds inside ExtractStuff
Is it OK to use the regular Thread.Sleep(1000)
? Or is there another way to pause the running task?
Upvotes: 3
Views: 12651
Reputation: 1196
You could use Task.Delay(timeout) and await that inside your ExtractStuff method.
private async string ExtractStuff(fileName)
{
// Your Code
await Task.Delay(timeout);
}
Upvotes: 0
Reputation: 27515
Thread.Sleep will block the thread running the Task (which is not ideal), but it can be an acceptable compromise (low risk and not a huge problem to performance) as long as you're not running a large number of tasks in parallel. .NET 4.5 has some improvements with 'async/await' and Task.Delay that will implicitly set up a continuation based on a timer (which doesn't require blocking a running thread), but this is not directly available in 4.0.
You can do the same thing yourself with something like this (not tested much, so use with caution):
class Program
{
static void Main(string[] args)
{
var fullAction = RunActionsWithDelay(DoSomething, 2000, DoSomethingElse);
fullAction.Wait();
Console.WriteLine("Done");
Console.ReadLine();
}
static Task RunActionsWithDelay(Action first, int delay, Action second)
{
var delayedCompletion = new TaskCompletionSource<object>();
var task = Task.Factory.StartNew(DoSomething);
task.ContinueWith(t =>
{
if (t.IsFaulted)
{
delayedCompletion.SetException(t.Exception);
}
else
{
Timer timer = null;
timer = new Timer(s =>
{
try
{
DoSomethingElse();
delayedCompletion.SetResult(null);
}
catch (Exception ex)
{
delayedCompletion.SetException(ex);
}
finally
{
timer.Dispose();
}
}, null, delay, Timeout.Infinite);
}
});
return delayedCompletion.Task;
}
static void DoSomething()
{
Console.WriteLine("Something");
}
static void DoSomethingElse()
{
Console.WriteLine("Something Else");
}
}
This is fairly ugly, though you can encapsulate it a bit better than the above. It does eliminate the 'hanging' thread, but there is additional performance overhead associated with setting up the continuations. I really only recommend doing this if you have a lot of parallel tasks running and they all need to introduce delays.
Upvotes: 3
Reputation: 4554
If you need to delay the execution of ExtractStuff you can take a look at ThreadPool.RegisterWaitForSingleObject and combine with an WaitHandle that is never set.
private static WaitHandle NeverSet = new WaitHandle();
private void ExtractStuff(object state)
{
string filename = state as string;
....
}
private void StartExtract(string filename);
{
ThreadPool.RegisterWaitForSingleObject(NeverSet, ExtractStuff, fileName, seconds * 1000, true);
}
Hope that this will help you in your quest.
Upvotes: 1
Reputation: 4766
I believe it is fine to do this but preferable to use TaskCreationOptions.LongRunning.
Task.Factory.StartNew(() =>
{
ExtractStuff(fileName);
},TaskCreationOptions.LongRunning);
Upvotes: 2