C# 按时间更改获取当前时间
我有以下代码来显示当前时间:C# 按时间更改获取当前时间,c#,multithreading,timer,clock,C#,Multithreading,Timer,Clock,我有以下代码来显示当前时间: static void Main(string[] args) { while (true) { ShowDate(GetTime(),GetDate()); //Here's my issue: System.Threading.Thread.Sleep(1000); } } //Clear Console and write current Date again. static void
static void Main(string[] args)
{
while (true)
{
ShowDate(GetTime(),GetDate());
//Here's my issue:
System.Threading.Thread.Sleep(1000);
}
}
//Clear Console and write current Date again.
static void ShowDate(String time, String date)
{
Console.Clear();
Console.WriteLine(date);
Console.WriteLine(time);
}
static string GetTime()
{
string timeNow = DateTime.Now.ToString("HH:mm:ss");
return timeNow;
}
static string GetDate()
{
string dateNow = DateTime.Now.ToString("dd.MM.yy");
return dateNow;
}
在我看来,Thread.Sleep(1000)
只显示程序启动后每秒测量的时间。所以它没有显示完全正确的时间。我可以尝试为Thread.Sleep()
设置一个较低的值,但这仍然有点不准确,可能会变得有点低效。
例如,是否有任何可能的方法可以在系统每次更新其时间时更新时间?类似于
事件监听器的东西
可能吗 不要使用线程。睡眠停止线程执行,我认为最好使用常规计时器:
static void Main(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer(1000);
timer.Elapsed += Tim_Elapsed;
timer.Start();
}
private void Tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
ShowDate();
}
与使用Thread.Sleep停止线程执行不同,我认为最好使用常规计时器:
static void Main(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer(1000);
timer.Elapsed += Tim_Elapsed;
timer.Start();
}
private void Tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
ShowDate();
}
如您所写,这将每秒刷新(写入)时间-0、1、2、3。。 但是,如果该程序在某个中间时间启动,它将像1.3、2.3、3.3那样运行 这并非总是预期的行为,但每次时间更改都会发生
事件
,这也会消耗时间-您可能知道存在一些“系统时间”,这些时间在刻度中计算
每次处理器跳转到下一条指令时都会出现勾号,由于它有一些频率,因此可以从中重新计算当前时间
但是,.NET
允许您使用一些预构建的计时器
,可以以毫秒的精度运行
示例代码:
使用系统;
使用系统线程;
公共静态类程序
{
公共静态void Main()
{
//创建一个知道调用TimerCallback的Timer对象
//方法每2000毫秒一次。
计时器t=新计时器(TimerCallback,null,0,2000);
//等待用户点击
Console.ReadLine();
}
专用静态void TimerCallback(对象o)
{
//显示调用此方法的日期/时间。
WriteLine(“In-TimerCallback:+DateTime.Now”);
//强制对此演示执行垃圾回收。
GC.Collect();
}
}
重要提示:您正在使用Thread.Sleep()
,这将导致线程停止其所有工作,这确实不是延迟某些活动的有效方法,应该尽量少用。有一些特殊的地方,它确实有用,但这肯定不是唯一的地方。如您所写,这将每秒刷新(写入)一次-0、1、2、3。。
但是,如果该程序在某个中间时间启动,它将像1.3、2.3、3.3那样运行
这并非总是预期的行为,但每次时间更改都会发生事件
,这也会消耗时间-您可能知道存在一些“系统时间”,这些时间在刻度中计算
每次处理器跳转到下一条指令时都会出现勾号,由于它有一些频率,因此可以从中重新计算当前时间
但是,.NET
允许您使用一些预构建的计时器
,可以以毫秒的精度运行
示例代码:
使用系统;
使用系统线程;
公共静态类程序
{
公共静态void Main()
{
//创建一个知道调用TimerCallback的Timer对象
//方法每2000毫秒一次。
计时器t=新计时器(TimerCallback,null,0,2000);
//等待用户点击
Console.ReadLine();
}
专用静态void TimerCallback(对象o)
{
//显示调用此方法的日期/时间。
WriteLine(“In-TimerCallback:+DateTime.Now”);
//强制对此演示执行垃圾回收。
GC.Collect();
}
}
重要提示:您正在使用Thread.Sleep()
,这将导致线程停止其所有工作,这确实不是延迟某些活动的有效方法,应该尽量少用。有一些特殊的ocation,在那里它确实是可用的,但这肯定不是唯一的一个。我将使用每秒发出事件的自定义时钟类来实现这一点。通过测量下一秒即将过去之前的剩余时间,我们可以等到那一刻,然后触发事件
利用async/await
带来代码清晰的好处,利用IDisposable
进行清理,这可能看起来像这样:
void Main()
{
using(var clock = new Clock())
{
clock.Tick += dt => Console.WriteLine(dt);
Thread.Sleep(20000);
}
}
//sealed so we don't need to bother with full IDisposable pattern
public sealed class Clock:IDisposable
{
public event Action<DateTime> Tick;
private CancellationTokenSource tokenSource;
public Clock()
{
tokenSource = new CancellationTokenSource();
Loop();
}
private async void Loop()
{
while(!tokenSource.IsCancellationRequested)
{
var now = DateTime.UtcNow;
var nowMs = now.Millisecond;
var timeToNextSecInMs = 1000 - nowMs;
try
{
await Task.Delay(timeToNextSecInMs, tokenSource.Token);
}
catch(TaskCanceledException)
{
break;
}
var tick = Tick;
if(tick != null)
{
tick(DateTime.UtcNow);
}
}
}
public void Dispose()
{
tokenSource.Cancel();
}
}
void Main()
{
使用(var clock=new clock())
{
clock.Tick+=dt=>Console.WriteLine(dt);
睡眠(20000);
}
}
//密封,所以我们不需要麻烦与完整的IDisposable模式
公共密封类时钟:IDisposable
{
公共事件行动;
私有取消令牌源令牌源;
公钟
{
tokenSource=新的CancellationTokenSource();
Loop();
}
私有异步void循环()
{
而(!tokenSource.IsCancellationRequested)
{
var now=DateTime.UtcNow;
var nowMs=now.毫秒;
var timeToNextSecInMs=1000-nowMs;
尝试
{
wait Task.Delay(timeToNextSecInMs,tokenSource.Token);
}
捕获(TaskCanceledException)
{
打破
}
var tick=tick;
如果(勾选!=null)
{
勾选(DateTime.UtcNow);
}
}
}
公共空间处置()
{
tokenSource.Cancel();
}
}
我将使用每秒发出事件的自定义时钟类来实现这一点。通过测量下一秒即将过去之前的剩余时间,我们可以等到那一刻,然后触发事件
利用async/await
带来代码清晰的好处,并利用IDisposable
进行清理,这可能类似于