【发布时间】:2017-03-16 20:49:04
【问题描述】:
我正在尝试与其他代码并行运行一个无限循环,该循环在 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
【问题讨论】:
-
如果我没看错,如果还剩不到一分钟,你还耽误一秒钟(
await Task.Delay(1000);)?哪怕只有半秒?那可能是你的问题。 -
如果您为此使用计划任务会有所帮助吗? Quartz.NET 是一个可以帮助你的库......另见:stackoverflow.com/questions/4529019/…
-
值得注意的是,除非您完全确定循环将每毫秒运行几次,否则您尝试执行的操作可能是不可能的,而外部因素(例如垃圾收集)可能会干扰。你可能会更好地为已经达到或超过的时间设置一个标志。
-
这里不相关但可能令人讨厌的错误:您使用
asynclambda 作为Parllel.Invoke的参数,它不提供异步支持。第二个参数 (Func<Task>) 只会阻塞,直到您点击await语句。如果您的第一个Action恰好在那时完成,Parallel.Invoke将完成并且程序将立即终止,而无需等待由async委托创建的Task完成。 -
没有确切的时间。这是宇宙量子性质的结果。你到底想做什么?您实际上需要多接近?
标签: c# task-parallel-library infinite-loop .net-core timespan