简体   繁体   English

当我使用Background Worker填充数据网格时,主UI线程正在挂起

[英]main UI thread is hanging when i am using Background Worker to fill the datagrid

I am developing a UI for network analyzer. 我正在为网络分析仪开发UI。 I am using WPF. 我正在使用WPF。 In my UI, i need to to update the incoming packets into a datagrid. 在我的UI中,我需要将传入的数据包更新为一个数据网格。 so here i am using a background worker class. 所以在这里我正在使用后台工作者类。 Now the filling of Datagrid is being done by background worker( i am filling datagrid in process_changed event handler). 现在,Datagrid的填充由后台工作人员完成(我正在process_changed事件处理程序中填充datagrid)。 Now i need to generate a click event once i clicked on row of datagrid and it prompts to another tab to give description... now the issue is, 1) when i use sleep(50) the the click event is working fine. 现在,我需要在单击datagrid的行后生成一个click事件,它会提示另一个选项卡以提供描述...现在的问题是,1)当我使用sleep(50)时,click事件运行良好。 2) if change the sleep value to 10, the click event in datagrid is working upto 17000 rows, later whole UI is not working, but the filling of datagrid is working 2)如果将sleep值更改为10,则datagrid中的click事件最多可以工作17000行,之后整个UI都无法工作,但是datagrid的填充正在工作

 public DatagridUsercontrol()
    {
        InitializeComponent();

    }
    public DatagridUsercontrol(MainWindow _parent)
    {
        InitializeComponent();
        mainParent = _parent;
        worker.WorkerReportsProgress = true;
        worker.DoWork += worker_DoWork;
        worker.ProgressChanged += worker_ProgressChanged;
        worker.WorkerSupportsCancellation = true;
        worker.RunWorkerCompleted += worker_RunWorkerCompleted;
    }
    private void Start_click(object sender, RoutedEventArgs e)
    {

        datagrid1.Items.Clear();
        packdata packda = new packdata();
        packda.allocatememory(mainParent.counttab_display-2/*mainParent.i-1*/);
        worker.RunWorkerAsync();
        StartCapture.IsEnabled = false;
        StopCapture.IsEnabled = true;
    }

    private void Stop_click(object sender, RoutedEventArgs e)
    {

        worker.CancelAsync();
        StopCapture.IsEnabled = false;
        //StartCapture.IsEnabled = true;

    }

    private void Capopt_Click(object sender, RoutedEventArgs e)
    {
        mainParent.CaptureOptions_Click(sender, e);

    }

        //[DllImport("CapturePackets.dll")]
       //  static extern packetinformation getheader( out byte[] data,  int size);
    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
       // int max = (int)e.Argument;
        int result = 0;
        Byte[] a2 = null; int j=0;
        for(int i = 0; ; i++)
        {
            packetinformation packetinfo = new packetinformation();
            packdata pack= new packdata();
            //arrayofdata a2 = new arrayofdata();

           // Byte[] a2 = { 0xC4, 0x00, 0x78, 0x00, 0xA8, 0x54, 0xB2, 0xA7, 0x61, 0x11, 0x00, 0x00, 0x00, 0x00 };
            /* Data to pass*/
            if (i % 2 == 0)
            {
               switch(j)
               {
                   case 0:
                    {
                        a2 = new Byte[] { 0xC4, 0x00, 0x78, 0x00, 0xA8, 0x54, 0xB2, 0xA7, 0x61, 0x11, 0x00, 0x00, 0x00, 0x00 }; //CTS
                        j++;
                        break;
                    }
                   case 1:
                    {
                        a2 = new Byte[] { 0xC0, 0x00, 0x3A, 0x11, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x20, 0xEF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 };//Deauthentication
                        j++;
                        break;
                    }
                   case 2:
                    {
                        a2 = new Byte[] {0x88,0x01,0x2C,0x00,0x00,0x21,0x1B,0x64,0xF1,0xBF,0x00,0x03,0x7F,0x40,0x83,0x99,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x10,0x00,0x00,0x00,0xAA,0xAA,0x03,0x00,0x00,0x00,0x08,0x06,0x00,0x01,0x08,0x00,0x06,0x04,
                          0x00,0x01,0x00,0x03,0x7F,0x40,0x83,0x99,0xC0,0xA8,0x05,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xA8,0x05,0x0F,0x00,0x00,0x00,0x00};// ARP
                        j++;
                        break;
                    }
                   case 3:
                    {
                        a2 = new Byte[] {0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x11,0x22,0x33,0x44,0x55,0x00,0x11,0x22,0x33,0x44,0x55,0x00,0x00,0x80,0x61,0x59,0x14,0x00,0x00,0x00,0x00,0x64,0x00,0x31,0x04,0x00,0x0B,0x4E,0x45,
                         0x54,0x47,0x45,0x41,0x52,0x5F,0x31,0x32,0x33,0x01,0x08,0x82,0x84,0x8B,0x96,0x0C,0x12,0x18,0x24,0x03,0x01,0x03,0x05,0x04,0x02,0x03,0x00,0x00,0x07,0x06,0x55,0x53,0x49,0x01,0x0B,0x1B,0x2A,0x01,0x00,0x32,
                         0x04,0x30,0x48,0x60,0x6C,0xDD,0x18,0x00,0x50,0xF2,0x02,0x01,0x01,0x0E,0x00,0x03,0xA4,0x00,0x00,0x27,0xA4,0x00,0x00,0x42,0x43,0x5E,0x00,0x62,0x32,0x2F,0x00,0x30,0x14,0x01,0x00,0x00,0x0F,0xAC,0x04,0x01,
                         0x00,0x00,0x0F,0xAC,0x04,0x01,0x00,0x00,0x0F,0xAC,0x01,0x01,0x00,0xDD,0x09,0x00,0x03,0x7F,0x01,0x01,0x00,0x00,0xFF,0x7F,0xDD,0x0A,0x00,0x03,0x7F,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
                        j = 0;
                        break;
                    }
                }
             }

            else
            {
                a2 = new Byte[] {0x88,0x01,0x2C,0x00,0x00,0x21,0x1B,0x64,0xF1,0xBF,0x00,0x03,0x7F,0x40,0x83,0x99,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x10,0x00,0x00,0x00,0xAA,0xAA,0x03,0x00,0x00,0x00,0x08,0x06,0x00,0x01,0x08,0x00,0x06,0x04,
                0x00,0x01,0x00,0x03,0x7F,0x40,0x83,0x99,0xC0,0xA8,0x05,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xA8,0x05,0x0F,0x00,0x00,0x00,0x00}; 
            }

            packetinfo=pack.getheader(a2,mainParent.counttab_display-2);
            result++;
            //int progressPercentage = Convert.ToInt32(((double)i / max) * 100);
            (sender as BackgroundWorker).ReportProgress(i,packetinfo);
            System.Threading.Thread.Sleep(50);

            /* with out the following code it wont cancel an background worker thread*/
            if (worker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }

        }
       // e.Result = result;
    }
   // packetinformation packinfo1 = new packetinformation();
    void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        //System.Threading.Thread.Sleep(2000);
        int i = e.ProgressPercentage;
        packetinformation packinfo1 = new packetinformation();
        packinfo1 = (packetinformation)e.UserState;
        Packet_add_Datagrid(packinfo1,i);
    }

i am not understanding where is issue is happening. 我不知道问题在哪里发生。 can anyone suggest me? 有人可以建议我吗?

Here I am pasting a partial code of packet_add_Datagrid()... 在这里我粘贴了packet_add_Datagrid()的部分代码...

 public void Packet_add_Datagrid(packetinformation packinfo1,int i)
    {

       // datagrid1.Items.Add(new test() { sno = 1, name = "ssss" });
      Byte Type = Convert.ToByte(packinfo1.version & 0x0C);
        string packetType;
        Byte SubType = Convert.ToByte(packinfo1.version & 0xF0);

        string packetSubType;
        packetType = "Null"; //here you need to assign a initial value otherwise it wont work
        packetSubType = "Null";

        {

      // here I did a parsing logics for all packets of WLAN

        }

      /* Here I used a code a to make a scrollbar to show the current entry of datagrid*/
            if (datagrid1.Items.Count > 0)
                {
                    var border = VisualTreeHelper.GetChild(datagrid1, 0) as Decorator;
                    if (border != null)
                    {
                        var scroll = border.Child as ScrollViewer;
                        if (scroll != null)
                        {

                            scroll.ScrollChanged += datagrid1_ScrollChanged;


                        }
                    }
                }
                }

the code for the datagrid1_ScrollChanged event is below 下面是datagrid1_ScrollChanged事件的代码

 public Boolean AutoScroll=true;
    private void datagrid1_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
           var border = VisualTreeHelper.GetChild(datagrid1, 0) as Decorator;
           if (border != null)
           {
               var scroll = border.Child as ScrollViewer;




        // User scroll event : set or unset autoscroll mode
             if (e.ExtentHeightChange == 0)
                 {     // Content unchanged : user scroll event
            if (scroll.VerticalOffset == scroll.ScrollableHeight)
                     {   // Scroll bar is in bottom
                // Set autoscroll mode
                AutoScroll = true;
            }
                     else
            {   // Scroll bar isn't in bottom
                // Unset autoscroll mode
                AutoScroll = false;
            }
        }

        // Content scroll event : autoscroll eventually
        if (AutoScroll && e.ExtentHeightChange != 0)
        {   // Content changed and autoscroll mode set
            // Autoscroll
            scroll.ScrollToVerticalOffset(scroll.ExtentHeight);
        }

      }

    }

thank you, sathish 谢谢,sathish

Possible reason, your worker_ProgressChanged() is blocking your UI 可能的原因,您的worker_ProgressChanged()阻止了您的UI

Why this happen, 为什么会这样

BackgroundWorker.ReportProgress( ) calls the event handler ProgressChanged event and this event runs on the same thread which BackgroundWorker was created BackgroundWorker.ReportProgress( )调用事件处理程序ProgressChanged event并且此事件在创建BackgroundWorker的同一线程上运行

The call to the ReportProgress method is asynchronous and returns immediately. 对ReportProgress方法的调用是异步的,并立即返回。 The ProgressChanged event handler executes on the thread that created the BackgroundWorker ProgressChanged事件处理程序在创建BackgroundWorker的线程上执行

So in your case, every time you try to update the datagrid your BackgroundWorker updates run on your UI 因此,就您而言,每次尝试更新datagrid BackgroundWorker更新都会在UI运行

Possible solution : 可能的解决方案:

Try to update datagrid periodically. 尝试定期更新datagrid That means buffer data and update when you have adequate amount of data . 这意味着缓冲数据并在有足够数据量时更新。

Ex : Update when you got 500 rows 例如:当您有500行时更新

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM