通常我避免使用Thread.Sleep
,除了测试或调试代码外,
在下面的示例中,我正在尝试运行一个控制台应用程序,该应用程序将运行不同的类,这些类别将在某些时间触发计时器滴答。这个想法是添加更多运行独立服务的类。
目前我正在使用的是,Thread.Sleep(10000);
只是为了保持控制台打开以允许代码运行。
肯定是Thread.Sleep
阻止了CPU的一些重新解析吗?
有更好的方法吗?(这是针对Windows和Linux的)
while(true)
{
Thread.Sleep(10000);
}
程序:
class Program
{
private static CultureInfo culture = new CultureInfo("en-gb");
static void Main(string[] args)
{
LongRunningClass longRunningClass = new LongRunningClass();
while(true)
{
Thread.Sleep(10000);
}
}
}
长期运行任务:
public class LongRunningClass
{
private Timer timer;
private List<TimeSpan> ScheduleTimes = new List<TimeSpan>()
{
new TimeSpan(4,0,0),
new TimeSpan(6,0,0),
new TimeSpan(21,0,0),
new TimeSpan(23,0,0),
};
public LongRunningClass()
{
this.timer = new Timer(1000);
this.timer.Elapsed += new ElapsedEventHandler(OnTick);
this.timer.Start();
}
protected virtual void OnTick(object sender, ElapsedEventArgs e)
{
this.timer.Stop();
RunLongRunningTask();
double nextTickInterval = 0;
TimeSpan timeOfDayNow = DateTime.Now.TimeOfDay;
foreach (TimeSpan scheduleTime in ScheduleTimes)
{
if (scheduleTime > timeOfDayNow)
{
nextTickInterval = (scheduleTime - timeOfDayNow).TotalMilliseconds;
break;
}
}
// If tick interval not set yet then restart for next day
if (nextTickInterval <= 0)
{
TimeSpan scheduleTime = ScheduleTimes[0].Add(new TimeSpan(1, 0, 0, 0));
nextTickInterval = (scheduleTime - timeOfDayNow).TotalMilliseconds;
}
this.timer.Interval = nextTickInterval;
this.timer.Start();
}
private void RunLongRunningTask()
{
// Long Running Task
}
}
如果是要保持控制台打开。你尝试过吗?
while(true)
{
Console.Read();
}
或仅:
Console.Read();
所以,除非您按键,否则它不会关闭。
您可以无限期地保持控制台打开,直到使用Autoresetevent取消用户:
:class Program
{
private static AutoResetEvent autoResetEvent;
private static CultureInfo culture = new CultureInfo("en-gb");
static void Main(string[] args)
{
LongRunningClass longRunningClass = new LongRunningClass();
WaitForCancel();
}
/// <summary>
/// When cancel keys Ctrl+C or Ctrl+Break are used, set the event.
/// </summary>
private static void WaitForCancel()
{
autoResetEvent = new AutoResetEvent(false);
Console.WriteLine("Press CTRL + C or CTRL + Break to exit...");
Console.CancelKeyPress += (sender, e) =>
{
e.Cancel = true;
autoResetEvent.Set();
};
autoResetEvent.WaitOne();
}
}
显然,此方法依靠您知道线程何时完成处理。
肯定是线程。
它不是您必须担心的CPU,而是它的内存。您可以在此处读取复杂的版本,但是简单的版本是每个线程使用1MB的内存用于堆栈。如果您正在编写需要很多线程的应用程序,则应考虑编写异步方法并使用Task.Delay
。这允许线程在方法等待时做其他事情,这可以减少处理相同工作量所需的线程总数。
在这种情况下,
没有太大的意义 - 虽然C#7.1确实支持异步主体,但它只是句法糖,并且不会释放线程以执行其他工作。在任何情况下,我都不会在这样的简单控制台应用中使用Thread.Sleep
,或者使用诸如NEOS07之类的Console.ReadLine
建议。
Thread.Sleep
仍然有效,但是您可以考虑在此处使用Task.Delay
作为替代方案,例如
await Task.Delay(1000);