我有这样的代码创建一个任务:如何暂停执行任务
Task.Factory.StartNew(() =>
{
ExtractStuff(fileName);
});
有时候,我需要暂停几秒钟内ExtractStuff
是否确定使用常规的Thread.Sleep(1000)
?还是有另一种方法来暂停正在运行的任务?
我有这样的代码创建一个任务:如何暂停执行任务
Task.Factory.StartNew(() =>
{
ExtractStuff(fileName);
});
有时候,我需要暂停几秒钟内ExtractStuff
是否确定使用常规的Thread.Sleep(1000)
?还是有另一种方法来暂停正在运行的任务?
我相信这样做很好,但最好使用TaskCreationOptions.LongRunning。
Task.Factory.StartNew(() =>
{
ExtractStuff(fileName);
},TaskCreationOptions.LongRunning);
我不明白这是如何涉及到这个问题? –
@James,这提示任务调度程序您的任务可能需要一段时间才能执行,因此它应该避免在Task中绑定一个有限的资源(如线程池)。这可能会产生一些额外开销(从分配新线程而不是使用池中的线程),但可能会阻止其他问题(多任务占用池并及时休眠,阻止其他任务启动)。你打算在你的任务中睡觉,你可能应该考虑自己长时间运行。 –
如果需要推迟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);
}
希望这会帮助你在你的追求。
不,我不需要延迟ExtractStuff的执行。我需要根据内部逻辑在中间暂停执行ExtractStuff。 – user1615362
Thread.Sleep会阻塞运行任务的线程(这并不理想),但只要没有运行大量数据,它可以是一个可以接受的折衷方案(低风险,性能不是很大的问题)并行的任务。 .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");
}
}
这是相当难看,但你可以封装比它上面好一点。它确实消除了“悬挂”线程,但是与设置延续相关的额外性能开销。如果你有很多并行任务正在运行,并且他们都需要引入延迟,我真的只是建议你这样做。
你说Thread.Sleep会阻塞运行任务的线程,但是如果我使用LongRunning,是不是会导致只有任务被暂停而不是运行任务的线程? – user1615362
+1,并感谢扩大我的答案,应该回到它。 –
@ user1615362'Thread.Sleep()'总是阻塞当前线程。如果你使用'LongRunning',它不会是'ThreadPool'中的一个线程,但它仍然是一些线程,所以它仍然是浪费。 – svick
您可以使用Task.Delay(超时)并等待您的ExtractStuff方法。
private async string ExtractStuff(fileName)
{
// Your Code
await Task.Delay(timeout);
}
当你说,是否可以使用Thread.Sleep(),你是什么意思? –
某些其他线程是否需要暂停某些工作? –
我的意思是它会暂停任务,或者它会暂停父线程。 – user1615362