简体   繁体   中英

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

I am developing a UI for network analyzer. I am using WPF. In my UI, i need to to update the incoming packets into a datagrid. 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). 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. 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

 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()...

 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

 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

Possible reason, your worker_ProgressChanged() is blocking your UI

Why this happen,

BackgroundWorker.ReportProgress( ) calls the event handler ProgressChanged event and this event runs on the same thread which BackgroundWorker was created

The call to the ReportProgress method is asynchronous and returns immediately. The ProgressChanged event handler executes on the thread that created the BackgroundWorker

So in your case, every time you try to update the datagrid your BackgroundWorker updates run on your UI

Possible solution :

Try to update datagrid periodically. That means buffer data and update when you have adequate amount of data .

Ex : Update when you got 500 rows

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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