2012-03-29 84 views
0

我的应用程序需要一个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(); 
+3

为什么你不希望使用定时器吗?这就是他们的目的。 – Steven 2012-03-29 17:10:31

+1

也许在循环中使用'Thread.Sleep'? – 2012-03-29 17:13:45

+0

我宁愿避免Thread.Sleep因为我想要的选项杀死中间停止按钮的prosecc,它是更简单的计时器? – user979033 2012-03-29 17:16:58

回答

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); 
        }); 
+0

指数超出范围,必须是非负数 – user979033 2012-03-29 17:44:08

+0

更新了答案 – Prakash 2012-03-29 17:52:15

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

相关问题