16
2019
04

VB/C#中实现延时(等待)的方法

使用Timer()函数
这是用的最多的一种方法,也是在VB联机手册中所推荐的。添加一个CommandButton控件,再将以下代码添加到代码窗口中:

Private Sub Command2_Click()
Dim Savetime As Single
Text1 = "Timer begin"
Savetime = Timer '记下开始的时间
While Timer < Savetime + 5 '循环等待
DoEvents '转让控制权,以便让操作系统处理其它的事件。
Wend
Text1 = "Timer ok"
End Sub

转自https://blog.csdn.net/autofei/article/details/645133


C#的办法:

public static bool Delay(int delayTime) 
{ 
DateTime now = DateTime.Now;
int s;
do {
TimeSpan spand = DateTime.Now - now;
s = spand.Seconds;
Application.DoEvents();
}
while (s < delayTime);
return true; 
}


配合上述进行延时且不卡UI的方法:

 this.BeginInvoke((EventHandler)(delegate { Delay(2); this.Enabled = true; }));
 //Delay(2)是等待两秒,两秒后运行窗口Enabled为真


WPF中的方法:

Dispatcher.Invoke(new Action(()=> Thread.Sleep(5000)),DispatcherPriority.Background);
//继续执行延时之后的操作,如messagebox等


C#不阻塞UI的方法:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
 
namespace ConsoleApp2
{
    public class Timer
    {
        public delegate void TimerCompleteDelegate();
 
        [DllImport("kernel32.dll")]
        static extern IntPtr CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string lpTimerName);
 
        [DllImport("kernel32.dll")]
        static extern bool SetWaitableTimer(IntPtr hTimer, [In] ref long ft, int lPeriod, TimerCompleteDelegate pfnCompletionRoutine, IntPtr pArgToCompletionRoutine, bool fResume);
 
        [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);
 
        [DllImport("User32.dll")]
        static extern int MsgWaitForMultipleObjects(int nCount, ref IntPtr handle, bool fWaitAll, int dwMilliseconds, int dwWakeMask);
 
 
        /// <summary>
        /// 不占用cpu,窗口不卡死,不影响其它代码执行
        /// </summary>
        /// <param name="time">单位毫秒</param>
        public static bool Sleep(int time)
        {
            TimerCompleteDelegate TimerComplete = new TimerCompleteDelegate(TimerCompleted);
            long Interval = -10 * time * 1000;//占8字节
            //创建计时器
            IntPtr handle = CreateWaitableTimer(IntPtr.Zero, true, "WaitableTimer");
            SetWaitableTimer(handle, ref Interval, 0, TimerComplete, IntPtr.Zero, true);
            //等待消息抵达
            while (MsgWaitForMultipleObjects(1, ref handle, false, -1, 255) != 0)
            {
                //转让权限
                Application.DoEvents();
            }
            return CloseHandle(handle);
        }
        private static void TimerCompleted()
        {
            // 一旦定时器过期,就执行例程。这是独立于调用OnTimeRebug事件的类实现的程序执行的。
        }
    }
}



« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。