[英]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.