我有这个创建任务的代码:
Task.Factory.StartNew(() =>
{
ExtractStuff(fileName);
});
有时我需要在里面暂停几秒钟ExtractStuff
用普通的可以Thread.Sleep(1000)
吗?还是有其他方法可以暂停正在运行的任务?
我有这个创建任务的代码:
Task.Factory.StartNew(() =>
{
ExtractStuff(fileName);
});
有时我需要在里面暂停几秒钟ExtractStuff
用普通的可以Thread.Sleep(1000)
吗?还是有其他方法可以暂停正在运行的任务?
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");
}
}
这相当难看,尽管您可以将其封装得比上面的要好一些。它确实消除了“挂起”线程,但是与设置延续相关的额外性能开销。如果你有很多并行任务正在运行并且它们都需要引入延迟,我真的只建议这样做。
我相信这样做很好,但最好使用TaskCreationOptions.LongRunning。
Task.Factory.StartNew(() =>
{
ExtractStuff(fileName);
},TaskCreationOptions.LongRunning);
如果您需要延迟 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);
}
希望这对您的探索有所帮助。
您可以使用 Task.Delay(timeout) 并在您的 ExtractStuff 方法中等待。
private async string ExtractStuff(fileName)
{
// Your Code
await Task.Delay(timeout);
}