计时器以秒为单位精确时间
Timer to exact time by seconds
我正在尝试 运行 一个与其他代码并行的无限循环,它在 SECOND 达到的特定时间执行一次。
在下面的代码中,我试图触及确切的午夜时间,即:00 hh: 00 mm: 00 sec
using System; // for Date/Time
using System.Threading.Tasks; // for Parallel
public class Program
{
public static void Main(string[] args)
{
Parallel.Invoke(
() =>
{
Console.WriteLine("Begin first task...");
}, // close first Action
async () =>
{
Console.WriteLine("Begin second task...");
var midNight = "00:00:00";
while (true)
{
TimeSpan duration = DateTime.Parse(midNight).Subtract(DateTime.Now);
Console.WriteLine("looping at: {0:00} Days, {1:00} Hours, {2:00} Minutes, {3:00} Seconds, {4:00} Milliseconds",
duration.Days, duration.Hours, duration.Minutes, duration.Seconds, duration.Milliseconds);
if(duration.Days >= 1)
await Task.Delay(8640000);
else if(duration.Hours >= 1)
await Task.Delay(360000);
else if(duration.Minutes >= 1)
await Task.Delay(60000);
else
await Task.Delay(1000);
if(duration == TimeSpan.Zero) {
Console.WriteLine("It is time... midnight is {0}", DateTime.Now);
} // close second Action `the async task`
) // end of Parallel.Invoke
} // End of Main
} // End of Program
我能够使 await
语句正常工作以达到要求的点,但是锁定条件 if(duration == TimeSpan.Zero)
永远不会变成 true
我可以通过更改条件来做到这一点:
if(duration == TimeSpan.Zero)
至:
if(duration.Days == 0 && duration.Hours == 0 && duration.Minutes == 0 && duration.Seconds == 0)
为了避免事件重复发生,我添加了另一个 await
关卡,所以新关卡变成了:
if(duration.Days >= 1)
await Task.Delay(8640000);
else if(duration.Hours >= 1)
await Task.Delay(360000);
else if(duration.Minutes >= 1)
await Task.Delay(60000);
else if(duration.Seconds >= 1)
await Task.Delay(1000);
else
await Task.Delay(500);
我尝试添加 if(duration.Milliseconds >= 1) await(1)
但没有成功,我的输出如下所示:
问题是,在您的情况下,duration
永远不会为零,它从加几毫秒到减几毫秒。
我会做什么:如果 duration
不到一秒,请等待 duration
,然后假设时机成熟。在代码中:
if (duration.Days >= 1)
await Task.Delay(8640000);
else if (duration.Hours >= 1)
await Task.Delay(360000);
else if (duration.Minutes >= 1)
await Task.Delay(60000);
else if (duration.Seconds >= 1)
await Task.Delay(1000);
else
{
// defensive check in case duration is already negative
// this should not normally happen, but is still possible
if (duration > TimeSpan.Zero)
await Task.Delay(duration);
Console.WriteLine("It is time... midnight is {0}", DateTime.Now);
}
这不会给你毫秒精度,但在正常情况下应该是正确的秒。
首先,您的程序无法像您展示的那样运行,因为您的 TimeSpan duration = DateTime.Parse(midNight).Subtract(DateTime.Now);
永远不会是正数。其次,您的主要功能几乎会立即 return 。无论如何,您可以尝试我的解决方案来解决您的问题:
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
public static void Main(string[] args)
{
Parallel.Invoke(
() =>{Console.WriteLine("Begin first task...");},
async () =>
{
Console.WriteLine("Begin second task...");
DateTime startDate = DateTime.Today;
while (true)
{
TimeSpan duration = DateTime.Now.Subtract(startDate);
Console.WriteLine("looping at: {0:00} Days, {1:00} Hours, {2:00} Minutes, {3:00} Seconds, {4:00} Milliseconds",
duration.Days, duration.Hours, duration.Minutes, duration.Seconds, duration.Milliseconds);
int delay = (int)(DateTime.Today.AddDays(1.0).Subtract(DateTime.Now).TotalMilliseconds/2);
await Task.Delay(delay>0?delay:0);
if(duration.Days >= 1)
{
Console.WriteLine("It is time... midnight is {0}", DateTime.Now);
startDate = DateTime.Today;
}
}
}
);
}
}
这不会为您提供超级精度,因为在普通 PC 上您无法获得它(您可以使用 IRQ 来获得更好的精度,但这样的解决方案要复杂得多)。
兼任概念教授 link to 10s version。
当时版本:
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
public static void Main(string[] args)
{
Parallel.Invoke(
async () =>
{
Console.WriteLine("Begin second task...");
TimeSpan eventTime = new TimeSpan(0,18,16,53,123); //set when run event (ex. 18:16:53.123)
DateTime endDate = DateTime.Today.Add(eventTime);
if(endDate<DateTime.Now) endDate = endDate.AddDays(1.0);
while (true)
{
TimeSpan duration = endDate.Subtract(DateTime.Now);
Console.WriteLine("looping at: {0:00} Days, {1:00} Hours, {2:00} Minutes, {3:00} Seconds, {4:00} Milliseconds", duration.Days, duration.Hours, duration.Minutes, duration.Seconds, duration.Milliseconds);
if(duration.TotalMilliseconds <= 0.0)
{
Console.WriteLine("It is time... {0}", DateTime.Now);
endDate = endDate.AddDays(1.0);
continue;
}
int delay = (int)(duration.TotalMilliseconds/2);
await Task.Delay(delay>0?delay:0);
}
}
);
Thread.Sleep(6000);
}
}
我正在尝试 运行 一个与其他代码并行的无限循环,它在 SECOND 达到的特定时间执行一次。 在下面的代码中,我试图触及确切的午夜时间,即:00 hh: 00 mm: 00 sec
using System; // for Date/Time
using System.Threading.Tasks; // for Parallel
public class Program
{
public static void Main(string[] args)
{
Parallel.Invoke(
() =>
{
Console.WriteLine("Begin first task...");
}, // close first Action
async () =>
{
Console.WriteLine("Begin second task...");
var midNight = "00:00:00";
while (true)
{
TimeSpan duration = DateTime.Parse(midNight).Subtract(DateTime.Now);
Console.WriteLine("looping at: {0:00} Days, {1:00} Hours, {2:00} Minutes, {3:00} Seconds, {4:00} Milliseconds",
duration.Days, duration.Hours, duration.Minutes, duration.Seconds, duration.Milliseconds);
if(duration.Days >= 1)
await Task.Delay(8640000);
else if(duration.Hours >= 1)
await Task.Delay(360000);
else if(duration.Minutes >= 1)
await Task.Delay(60000);
else
await Task.Delay(1000);
if(duration == TimeSpan.Zero) {
Console.WriteLine("It is time... midnight is {0}", DateTime.Now);
} // close second Action `the async task`
) // end of Parallel.Invoke
} // End of Main
} // End of Program
我能够使 await
语句正常工作以达到要求的点,但是锁定条件 if(duration == TimeSpan.Zero)
永远不会变成 true
我可以通过更改条件来做到这一点:
if(duration == TimeSpan.Zero)
至:
if(duration.Days == 0 && duration.Hours == 0 && duration.Minutes == 0 && duration.Seconds == 0)
为了避免事件重复发生,我添加了另一个 await
关卡,所以新关卡变成了:
if(duration.Days >= 1)
await Task.Delay(8640000);
else if(duration.Hours >= 1)
await Task.Delay(360000);
else if(duration.Minutes >= 1)
await Task.Delay(60000);
else if(duration.Seconds >= 1)
await Task.Delay(1000);
else
await Task.Delay(500);
我尝试添加 if(duration.Milliseconds >= 1) await(1)
但没有成功,我的输出如下所示:
问题是,在您的情况下,duration
永远不会为零,它从加几毫秒到减几毫秒。
我会做什么:如果 duration
不到一秒,请等待 duration
,然后假设时机成熟。在代码中:
if (duration.Days >= 1)
await Task.Delay(8640000);
else if (duration.Hours >= 1)
await Task.Delay(360000);
else if (duration.Minutes >= 1)
await Task.Delay(60000);
else if (duration.Seconds >= 1)
await Task.Delay(1000);
else
{
// defensive check in case duration is already negative
// this should not normally happen, but is still possible
if (duration > TimeSpan.Zero)
await Task.Delay(duration);
Console.WriteLine("It is time... midnight is {0}", DateTime.Now);
}
这不会给你毫秒精度,但在正常情况下应该是正确的秒。
首先,您的程序无法像您展示的那样运行,因为您的 TimeSpan duration = DateTime.Parse(midNight).Subtract(DateTime.Now);
永远不会是正数。其次,您的主要功能几乎会立即 return 。无论如何,您可以尝试我的解决方案来解决您的问题:
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
public static void Main(string[] args)
{
Parallel.Invoke(
() =>{Console.WriteLine("Begin first task...");},
async () =>
{
Console.WriteLine("Begin second task...");
DateTime startDate = DateTime.Today;
while (true)
{
TimeSpan duration = DateTime.Now.Subtract(startDate);
Console.WriteLine("looping at: {0:00} Days, {1:00} Hours, {2:00} Minutes, {3:00} Seconds, {4:00} Milliseconds",
duration.Days, duration.Hours, duration.Minutes, duration.Seconds, duration.Milliseconds);
int delay = (int)(DateTime.Today.AddDays(1.0).Subtract(DateTime.Now).TotalMilliseconds/2);
await Task.Delay(delay>0?delay:0);
if(duration.Days >= 1)
{
Console.WriteLine("It is time... midnight is {0}", DateTime.Now);
startDate = DateTime.Today;
}
}
}
);
}
}
这不会为您提供超级精度,因为在普通 PC 上您无法获得它(您可以使用 IRQ 来获得更好的精度,但这样的解决方案要复杂得多)。
兼任概念教授 link to 10s version。
当时版本:
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
public static void Main(string[] args)
{
Parallel.Invoke(
async () =>
{
Console.WriteLine("Begin second task...");
TimeSpan eventTime = new TimeSpan(0,18,16,53,123); //set when run event (ex. 18:16:53.123)
DateTime endDate = DateTime.Today.Add(eventTime);
if(endDate<DateTime.Now) endDate = endDate.AddDays(1.0);
while (true)
{
TimeSpan duration = endDate.Subtract(DateTime.Now);
Console.WriteLine("looping at: {0:00} Days, {1:00} Hours, {2:00} Minutes, {3:00} Seconds, {4:00} Milliseconds", duration.Days, duration.Hours, duration.Minutes, duration.Seconds, duration.Milliseconds);
if(duration.TotalMilliseconds <= 0.0)
{
Console.WriteLine("It is time... {0}", DateTime.Now);
endDate = endDate.AddDays(1.0);
continue;
}
int delay = (int)(duration.TotalMilliseconds/2);
await Task.Delay(delay>0?delay:0);
}
}
);
Thread.Sleep(6000);
}
}