backgroundworker vs Event

时间:2012-03-29 13:56:57

标签: c# winforms

我使用我的Winform应用程序将数据包的缓冲区发送到我的网卡,我的应用程序显示通过进度条进展,如果我选择发送所有缓冲区没有任何延迟我的应用程序卡住的数据包(变成灰色)并且只有在整理所有缓冲区后才会恢复正常行为(如果我的缓冲区非常大,类似于> 50,000个数据包) 那我怎么处理这种情况呢?也许改变那些用事件来检查我所有的类属性(数据包发送数量......)的背景工作者?

    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);
                pcap.evePacketProgress += new Pcap.dlgPacketProgress(
                    (progressCount) =>
                    {
                        pcap._fileSelectedIndex = i;
                        bgWoSingle.ReportProgress(progressCount, pcap);
                    });

                if (selectedAdapter != null)
                {
                    //play the file
                    bContinuePlay = pcap.playCapture(selectedAdapter._packetDevice);                     }
            }

            loopsCount++;
        }

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

        }
        );

    bgWoSingle.RunWorkerAsync();

这里我检查类属性(类名是pcap):

void bgW_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    //check the properties and update the UI
    labelPacketSent.Text = pcap._numberOfSendPackets.ToString("#,##0"); 
    progressBar1.Value = e.ProgressPercentage;
}

3 个答案:

答案 0 :(得分:1)

你必须使用BackGroundWorker。我正在为它添加一个小例子。

private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
      backgroundWorker.ReportProgress(80, 15000);
}

private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
     var numberOfPackets = int.parse(e.UserState);

     MessageBox.Show("Percentage: " + e.ProgressPercentage );
     MessageBox.Show("Packets sent :" + numberOfPackets);  
}

工作人员可以通过UserState发送完成百分比或任何其他数据。

答案 1 :(得分:0)

我们的想法是拥有一个使用BGWorker的PacketSender类,并注册它的Progress事件等,并拥有一个或多个progress属性,以允许绑定/监听。

然后,PacketSender类将接收一些大任务,并让它的BGWorker做到这一点。您的BGWorker-Work方法将在一个单独的线程上,每次从其中调用ReportProgress时,您将在主线程中的PacketSender中的侦听方法中获取它,并且能够将其向上冒泡到PacketSender.ProgressChanged侦听器或更改百分比完成等的ProgressChanged属性

正确的方法是在PacketSender ctor中获取任务的数据,并立即启动BGWorker,以防止在同一个PacketSender上有多个任务,或者使用Start和Stop方法检查是否BGWorker正在运行,并将阻止单个PacketSender的多任务处理。

答案 2 :(得分:0)

最好在这里使用BackgroundWorker。它比定义自定义事件以更新进度条更新,更好。检查MSDN