C#里怎么用比较高效率的方式判断时间过去了一秒?

哈利_蜘蛛侠 2019-03-12 01:11:44
比如我的程序有一个主循环,while(true)那样子的,需要每隔一秒钟去做一件给定的事情。如果是在在C++里,那么我每次循环的时候都用
time(NULL)
来获得当前时间,然后与上次做事情的时间去比较就好了,因为这个开销还是很小的;然而在C#中,貌似最常用的获取时间的方式是通过类DateTime,但是这个类比较臃肿,效率应该低一些吧,所以有什么别的好方法呢?
我找了一下,找到System.Timers.Timer类,可以设定为给定时间后去做某事(还可以无限循环),不过不知道这个的效率怎么样。大家有何高见?
...全文
1767 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
平底锅锅锅 2019-04-04
  • 打赏
  • 举报
回复
定时器。Timer。
  • 打赏
  • 举报
回复
给你写一个简单的 demo:
using System;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            test();
            Console.WriteLine(".......按任意键退出");
            Console.ReadKey();
        }

        static async void test()
        {
            while (true)
            {
                Console.WriteLine(DateTime.Now.ToString("H:mm:ss.fff"));
                await Task.Delay(1000);
            }
        }
    }
}
以后,我不会再在这里纠结什么“线程”的说法,因为我觉得各种语言各种平台都在强调 Task 时代已经很普遍了,再满口是过时的线程概念会出很大的问题的。
  • 打赏
  • 举报
回复

int 秒 = DateTime.Now.Second;
do
{
if (DateTime.Now.Second != 秒)
{
//要执行的代码
break;
}
Application.DoEvents();
} while (true);

我用这个每秒执行最为简单。
泡泡龙 2019-03-18
  • 打赏
  • 举报
回复
定时器回调就行了
  • 打赏
  • 举报
回复
我所强调的是此时的工程和系统设计背景,注意不是在纠结个别语句。
  • 打赏
  • 举报
回复
所谓“开销”,实际上编写实用程序的人在程序——包括系统的和自定义的各种组件——中何止几万、几十万了需要“监控、判断、等待”的事件?!没学过异步概念的人,说到头,顶多学了一半的编程设计概念,所以遇到类似的设计需求就怂了,就只知道拿个线程去阻塞的做法了。 异步不是多线程。异步编程设计就是“不阻塞”。只有不阻塞的技术,才有可能是高效率的。程序逻辑到处采用阻塞思路的,必定很容易半身不遂。
jx315425246 2019-03-16
  • 打赏
  • 举报
回复
a.gettime += a.OngettimeHander(startime);
写错一句,相信大家都看的出来
  • 打赏
  • 举报
回复
用System.Timers.Timer类最好,WHILE中用阻塞或挂起引起不可知的事情;
例如作个文字提示功能:
if (shijian.Second % 2 == 0 && !this.Text.Contains("(提醒!)")) this.Text += "(提醒!)"; else this.Text = this.Text.Replace("(提醒!)", "");
运行结果是定时按每秒闪动,而用阻塞每秒闪动5次!不知是何缘由?用挂起有时漏秒。
  • 打赏
  • 举报
回复
Thread.Sleep(1000); 用这个 休眠 。
jx315425246 2019-03-16
  • 打赏
  • 举报
回复
这个效率比较高吧,如果写进你的程序,可以国样写
class a
{
int i;

public delegate void OngettimeHander(int t1);
public event OngettimeHander gettime;

Thread pro = new Thread(new ThreadStart(startime));
pro.IsBackground = true;
i=0;
pro.Start();


private void startime()
{
Thread.Sleep(500);
i++
gettime(i);
}
}

a a1=new a();
a.gettime += a.OngettimeHander(startime);

private void startime(int q) //第 0.5秒调用一次
{
if(q/2){}

}
  • 打赏
  • 举报
回复
不想设计 Timer 那么复杂的事件代码,那么就用 await Task.Delay 这样的异步代码。 本质上是一样的,即不论是事件还是异步代码,都是异步的。
pstrunner 2019-03-15
  • 打赏
  • 举报
回复
引用 16 楼 哈利_蜘蛛侠 的回复:
[quote=引用 15 楼 pstrunner 的回复:] 如果获取时间这点性能都不能忍受,那建议楼主调用本地接口;这样效率肯定比托管代码效率高。
本地接口是啥? 我找了一下,觉得System.Timers.Timer对象最好,不过我不想要多一个线程,就把它绑定到了一个控件上。[/quote] 就是直接调用系统API,例如Win32的timeGetTime等
牧歌ing 2019-03-15
  • 打赏
  • 举报
回复
Task.Delay 好了 异步延迟、不阻塞、可取消
xiaoxiangqing 2019-03-14
  • 打赏
  • 举报
回复
用await要好一些,不阻塞当前线程
  • 打赏
  • 举报
回复
引用 9 楼 jx315425246 的回复:
作一个委托,另外作一个线程,500毫秒一次, 如下: int i; public delegate void OngettimeHander(int t1); public event OngettimeHander gettime; Thread pro = new Thread(new ThreadStart(startime)); pro.IsBackground = true; i=0; pro.Start(); private void startime() { Thread.Sleep(500); i++ gettime(i); }
滥用“线程”概念坑爹啊。
引用 10 楼 良朋 的回复:
用Ticks最准确,第 21 个世纪以来所经历的计时周期数,可以精确到毫微秒,而且它是int64一直累加的,用它不会出错。 或者用 System.Environment.TickCount; 它包含自上次启动计算机以来所经过的时间(以毫秒为单位)。 以下代码用while延长1秒,不过可能会被CP批评。

    int x = System.Environment.TickCount;
            while (System.Environment.TickCount - x < 1000)
            {
                
            }
一个长整数它(名义上)代表了什么含义,跟windows桌面操作实际能如何进行时钟中断和应用层业务进程消息操作,是两回事儿。就好像普通人如果嘴上说“我能飞”这纯粹是意淫。
良朋 2019-03-14
  • 打赏
  • 举报
回复
用Ticks最准确,第 21 个世纪以来所经历的计时周期数,可以精确到毫微秒,而且它是int64一直累加的,用它不会出错。 或者用 System.Environment.TickCount; 它包含自上次启动计算机以来所经过的时间(以毫秒为单位)。 以下代码用while延长1秒,不过可能会被CP批评。

    int x = System.Environment.TickCount;
            while (System.Environment.TickCount - x < 1000)
            {
                
            }
jx315425246 2019-03-14
  • 打赏
  • 举报
回复
作一个委托,另外作一个线程,500毫秒一次,
如下:
int i;

public delegate void OngettimeHander(int t1);
public event OngettimeHander gettime;

Thread pro = new Thread(new ThreadStart(startime));
pro.IsBackground = true;
i=0;
pro.Start();


private void startime()
{
Thread.Sleep(500);
i++
gettime(i);
}

哈利_蜘蛛侠 2019-03-14
  • 打赏
  • 举报
回复
引用 15 楼 pstrunner 的回复:
如果获取时间这点性能都不能忍受,那建议楼主调用本地接口;这样效率肯定比托管代码效率高。
本地接口是啥? 我找了一下,觉得System.Timers.Timer对象最好,不过我不想要多一个线程,就把它绑定到了一个控件上。
pstrunner 2019-03-14
  • 打赏
  • 举报
回复
如果获取时间这点性能都不能忍受,那建议楼主调用本地接口;这样效率肯定比托管代码效率高。
CoveringLight 2019-03-14
  • 打赏
  • 举报
回复
引用 10 楼 良朋的回复:
用Ticks最准确,第 21 个世纪以来所经历的计时周期数,可以精确到毫微秒,而且它是int64一直累加的,用它不会出错。 或者用 System.Environment.TickCount; 它包含自上次启动计算机以来所经过的时间(以毫秒为单位)。 以下代码用while延长1秒,不过可能会被CP批评。

    int x = System.Environment.TickCount;
            while (System.Environment.TickCount - x < 1000)
            {
                
            }
会被批评有点真实啊2333
加载更多回复(8)

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧