Запускать событие каждые несколько миллисекунд без использования таймера - PullRequest
0 голосов
/ 29 марта 2012

Мое приложение принимает файл Wireshark и воспроизводит пакеты.Из основного потока я проверяю свой класс, который воспроизводит пакеты и обновляет мой графический интерфейс, и я хочу запускать событие обновления каждые 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 голосов
/ 29 марта 2012

Вы можете сделать игровой цикл и проверить истекшее время, используя объект 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

0 голосов
/ 29 марта 2012

Вы можете иметь массив экземпляров 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);
                    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...