我有这个代码创建一个任务:
Task.Factory.StartNew(() =>
{
ExtractStuff(fileName);
});
有时我需要在ExtractStuff
使用常规Thread.Sleep(1000)
可以吗?或者有其他方法可以暂停正在运行的任务吗?
答案 0 :(得分:3)
Thread.Sleep将阻止运行Task的线程(这不是理想的),但只要你没有运行大量的并行的任务。 .NET 4.5对'async / await'和Task.Delay进行了一些改进,它将隐式设置基于计时器的延续(不需要阻止正在运行的线程),但这不能直接在4.0中使用。
你可以用这样的东西自己做同样的事情(没有经过多少测试,所以谨慎使用):
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");
}
}
这是相当丑陋的,虽然你可以比上面更好地封装它。它确实消除了“挂起”线程,但是设置延续会产生额外的性能开销。我真的只建议这样做,如果你有很多并行任务在运行,他们都需要引入延迟。
答案 1 :(得分:2)
我认为这样做很好,但最好使用TaskCreationOptions.LongRunning。
Task.Factory.StartNew(() =>
{
ExtractStuff(fileName);
},TaskCreationOptions.LongRunning);
答案 2 :(得分:1)
如果你需要延迟ExtractStuff的执行,你可以看看ThreadPool.RegisterWaitForSingleObject并与一个从未设置的WaitHandle结合。
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);
}
希望这能帮助你完成任务。
答案 3 :(得分:0)
您可以使用Task.Delay(超时)并在ExtractStuff方法中等待它。
private async string ExtractStuff(fileName)
{
// Your Code
await Task.Delay(timeout);
}