2017-02-20 22 views
0

У меня следующий код, чтобы показать текущее время:Получить текущее время изменения времени

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(), но это все еще неточно и, вероятно, становится неэффективным. Есть ли какой-либо возможный способ, например, обновлять время каждый раз, когда система сама обновляет свое время? Может быть, что-то вроде event listener?

+3

как вы имеете в виду его "своего рода неточными? –

+1

Что вам нужно сделать ?. – NicoRiff

+0

Непонятно, чего вы пытаетесь достичь. Вы просто хотите отображать текущее время и время с интервалом в 1 секунду? –

ответ

1

Как Вы написали, это обновить бы (запись) время каждый второй - 0, 1, 2, 3 .. но если программа начнется в каком-то среднее время, она будет идти как 1,3, 2,3, 3,3

Это не всегда ожидаемое поведения, но Event для каждого изменения времени, будет также потребляться - возможно, вы знаете, что существует некоторое «системное время», которое подсчитывается в Ticks.

Отметка появляется каждый раз, когда процессор jumps соответствует следующей инструкции, и поскольку он имеет frequency, он может повторно рассчитать текущее время от него.

Однако .NET позволяет использовать предварительную сборку Timers, которая может работать с преломлением милисекунды.

Пример кода as in here:

using System; 
using System.Threading; 

public static class Program 
{ 
    public static void Main() 
    { 
     // Create a Timer object that knows to call our TimerCallback 
     // method once every 2000 milliseconds. 
     Timer t = new Timer(TimerCallback, null, 0, 2000); 
     // Wait for the user to hit <Enter> 
     Console.ReadLine(); 
    } 

    private static void TimerCallback(Object o) 
    { 
     // Display the date/time when this method got called. 
     Console.WriteLine("In TimerCallback: " + DateTime.Now); 
     // Force a garbage collection to occur for this demo. 
     GC.Collect(); 
    } 
} 

Важно: Вы используете Thread.Sleep(), что приведет к Thread Стопп всю свою работу, это действительно способ недостаточна задержки какой-либо деятельности и следует использовать минимально. Есть некоторые специальные ocasions, где это действительно полезно, но это, безусловно, не одно.

1

Вместо того, чтобы использовать 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

Ну, спасибо. Таймер более точен? И не прерывает текущий поток? –

+0

System.Timers.Timer (не путайте с другими классами таймера) запускается в пуле системных потоков, поэтому он не блокирует ваш основной поток. Он всегда запускается в указанное вами время, начиная с определенного времени, которое вызывает метод Start(). Пример: если вы запустите метод в 22: 31: 15.332, он снова запустится в 22: 31: 16.332, а не в 22: 31: 16.000 – NicoRiff

3

Я бы подошел к этому с помощью пользовательского класса часов, который испускает события каждую секунду. Измеряя оставшееся время до следующей секунды из-за истечения срока, мы можем подождать до этого момента, а затем запустить событие.

Использование 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(); 
    } 
} 
+0

Мне нравится этот ответ, поскольку подобная система используется в играх для обновления в определенных кадрах, ставка. – Tatranskymedved

 Смежные вопросы

  • Нет связанных вопросов^_^