每隔几毫秒启动一次事件而不使用计时器

时间:2012-03-29 17:04:58

标签: c# winforms

我的应用程序获取Wireshark文件并播放数据包。从主线程我正在检查我的类,它播放数据包并更新我的gui,我想每200毫秒启动我的更新事件而不是一直没有使用计时器(winform应用程序)

        listBoxFiles.SetSelected(0, true);
        bgWoSingle = new BackgroundWorker();
        bgWoSingle.WorkerReportsProgress = true;
        bgWoSingle.ProgressChanged += new ProgressChangedEventHandler(bgW_ProgressChanged);
        bgWoSingle.DoWork += new DoWorkEventHandler(
        (s3, e3) =>
        {
            while (loopsCount < numberOfLoops && bContinuePlay && ifContinue)
            {
                for (int i = 0; (i < listBoxFiles.Items.Count) && bContinuePlay && ifContinue; i++)
                {
                    this.Invoke((MethodInvoker)delegate
                    {
                        lbCurrentFileNum.Text = "(" + (i + 1) + "/" + listBoxFiles.Items.Count + "):";
                    });

                    string path = (string)listBoxFiles.Items[i];
                    pcap = new Pcap(path, playSpeed, isSync);
                    pcap._startTimer += new EventHandler(pcap_packetStartTimer);
                    pcap._stopTimer += new EventHandler(pcap__packetStopTimer);
                    //this is the event i want to fire every 200 milliseconds
                    *********************************************************
                    pcap.evePacketProgress += new Pcap.dlgPacketProgress(
                        (progressCount) =>
                        {
                            pcap._fileSelectedIndex = i;
                            bgWoSingle.ReportProgress(progressCount, pcap);
                        });
                   *********************************************************

                    if (selectedAdapter != null)
                    {
                        bContinuePlay = pcap.playCapture(selectedAdapter._packetDevice);
                    }
                }

                loopsCount++;
            }

        });

        bgWoSingle.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
            (s3, e3) =>
            {

            }
            );

        bgWoSingle.RunWorkerAsync();

2 个答案:

答案 0 :(得分:0)

您可以拥有一组DateTime实例。

var lastTimes = new DateTime[listBoxFiles.Items.Count];

并使用它们如下。

 pcap.evePacketProgress += new Pcap.dlgPacketProgress((progressCount) =>
                    {
                        pcap._fileSelectedIndex = i;
                        if(lastTimes[i] !=null && DateTime.Now-lastTimes[i] <= new TimeSpan(0,0,0,0,200))
                             return;
                        lastTimes[i]  = DateTime.Now;
                        bgWoSingle.ReportProgress(progressCount, pcap);
                    });

答案 1 :(得分:0)

您可以使用Stopwatch对象进行游戏循环并检查已用时间。我有一个带有复选框的表单(活动与否活动),以及一个可视化验证的文本框。对于每个刻度,我在文本框中添加|

public partial class RunningForm : Form
{
    #region Windows API - User32.dll
    [StructLayout(LayoutKind.Sequential)]
    public struct WinMessage
    {
        public IntPtr hWnd;
        public Message msg;
        public IntPtr wParam;
        public IntPtr lParam;
        public uint time;
        public System.Drawing.Point p;
    }

    [System.Security.SuppressUnmanagedCodeSecurity] // We won't use this maliciously
    [DllImport("User32.dll", CharSet=CharSet.Auto)]
    public static extern bool PeekMessage(out WinMessage msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags);

    [System.Security.SuppressUnmanagedCodeSecurity] // We won't use this maliciously
    [DllImport("user32.dll")]
    public static extern int SendNotifyMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

    #endregion

    Stopwatch sw;
    public event EventHandler RepeatTick;

    public RunningForm()
    {
        InitializeComponent();
        this.sw=new Stopwatch();
    }

    public void UpdateForm()
    {
        // Check if 200ms have passed
        if(sw.ElapsedMilliseconds>=200 )
        {
            if(this.RepeatTick!=null)
            {
                this.RepeatTick(this, System.EventArgs.Empty);
            }
            sw.Reset();
            sw.Start();
        }
    }

    #region Main Loop
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        sw.Start();
        // Hook the application's idle event
        System.Windows.Forms.Application.Idle+=new EventHandler(OnApplicationIdle);
        this.RepeatTick+=new EventHandler(RunningForm_RepeatTick);
    }

    void RunningForm_RepeatTick(object sender, EventArgs e)
    {
        textBox1.AppendText("|");
    }

    private void OnApplicationIdle(object sender, EventArgs e)
    {
        while(AppStillIdle)
        {
            if(checkBox1.Checked)
            {
                UpdateForm();
            }
        }
    }

    private bool AppStillIdle
    {
        get
        {
            WinMessage msg;
            return !PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
        }
    }
    #endregion
}

结果:

RunningForm Screenshot