簡體   English   中英

當我使用Background Worker填充數據網格時,主UI線程正在掛起

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

我正在為網絡分析儀開發UI。 我正在使用WPF。 在我的UI中,我需要將傳入的數據包更新為一個數據網格。 所以在這里我正在使用后台工作者類。 現在,Datagrid的填充由后台工作人員完成(我正在process_changed事件處理程序中填充datagrid)。 現在,我需要在單擊datagrid的行后生成一個click事件,它會提示另一個選項卡以提供描述...現在的問題是,1)當我使用sleep(50)時,click事件運行良好。 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);
    }

我不知道問題在哪里發生。 有人可以建議我嗎?

在這里我粘貼了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;


                        }
                    }
                }
                }

下面是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);
        }

      }

    }

謝謝,sathish

可能的原因,您的worker_ProgressChanged()阻止了您的UI

為什么會這樣

BackgroundWorker.ReportProgress( )調用事件處理程序ProgressChanged event並且此事件在創建BackgroundWorker的同一線程上運行

對ReportProgress方法的調用是異步的,並立即返回。 ProgressChanged事件處理程序在創建BackgroundWorker的線程上執行

因此,就您而言,每次嘗試更新datagrid BackgroundWorker更新都會在UI運行

可能的解決方案:

嘗試定期更新datagrid 這意味着緩沖數據並在有足夠數據量時更新。

例如:當您有500行時更新

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM