C# 后台工作人员+;wpf->;冻结窗口
-进度条始终为0% -窗户是弗罗森(而道尔克r.) -如果System.threading.thread.sleep(1)开启-工作正常 有什么问题吗C# 后台工作人员+;wpf->;冻结窗口,c#,wpf,progress-bar,backgroundworker,C#,Wpf,Progress Bar,Backgroundworker,-进度条始终为0% -窗户是弗罗森(而道尔克r.) -如果System.threading.thread.sleep(1)开启-工作正常 有什么问题吗 private void btnNext_Click(object sender, RoutedEventArgs e) { this._worker = new BackgroundWorker(); this._worker.DoWork += delegate(object s, DoWorkEventArgs args)
private void btnNext_Click(object sender, RoutedEventArgs e)
{
this._worker = new BackgroundWorker();
this._worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
long current = 1;
long max = generalMaxSzam();
for (int i = 1; i <= 30; i++)
{
for (int j = i+1; j <= 30; j++)
{
for (int c = j+1; c <= 30; c++)
{
for (int h = c+1; h <= 30; h++)
{
for (int d = h+1; d <= 30; d++)
{
int percent = Convert.ToInt32(((decimal)current / (decimal)max) * 100);
this._worker.ReportProgress(percent);
current++;
//System.Threading.Thread.Sleep(1); - it works well
}
}
}
}
}
};
this._worker.WorkerReportsProgress = true;
this._worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
this.Close();
};
this._worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args)
{
this.statusPG.Value = args.ProgressPercentage;
};
this._worker.RunWorkerAsync();
}
<Window x:Class="SzerencsejatekProgram.Create"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Létrehozás" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Height="500" Width="700">
<DockPanel>
<Button DockPanel.Dock="Right" Name="btnNext" Width="80" Click="btnNext_Click">Tovább</Button>
<StatusBar DockPanel.Dock="Bottom">
<StatusBar.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</StatusBar.ItemsPanel>
<StatusBarItem Grid.Column="1">
<TextBlock Name="statusText"></TextBlock>
</StatusBarItem>
<StatusBarItem Grid.Column="2">
<ProgressBar Name="statusPG" Width="80" Height="18" IsEnabled="False" />
</StatusBarItem>
<StatusBarItem Grid.Column="3">
<Button Name="statusB" IsCancel="True" IsEnabled="False">Cancel</Button>
</StatusBarItem>
</StatusBar>
</DockPanel>
</Window>
private void btnNext\u单击(对象发送方,路由目标)
{
这是._worker=newbackgroundworker();
此._worker.DoWork+=委托(对象s,doworkerEventArgs参数)
{
长电流=1;
long max=generalmaxzam();
对于(inti=1;i您的代码运行一个非常紧密的循环,并在其中心调用ReportProgress()
这意味着您的MessageQueue中充斥着执行进度更新的请求
如果在Bgw线程中构建一些延迟(Thread.Sleep(100)),您将看到响应性得到改善
更实用的解决方案是将报告转移到外部循环。在您的情况下:
for (int i = 1; i <= 30; i++)
{
int percent = (i * 100) / 30;
_worker.ReportProgress(percent);
for(int j = 0; ....)
....
}
for(int i=1;i
这很好。您的ProgressChanged事件匿名方法将在UI线程上运行。由于您报告的是频繁的进度,因此调度程序会将其排队并阻止UI。或基于%10(00)的报告或者是这样……有一位同事目前也有同样的问题,因为他正在报告250000条记录的进度。thread.Sleep(100)->这不是一个解决方案。我认为报告越少越好work@cyber,@Value:当然是Sleep()不适用于真正的程序。但是这个内部循环只增加了一个变量。我的答案稍微扩展了一点。嗯,它是ProgressUpdate的30^5倍,所以我仍然希望报告较少的进度。ProgressUpdate的目标通常是向用户显示系统没有死,因为他们并不真正关心你是否有1000万或10000万记录(除非你故意告诉他们你将完成多少项。啊,没有看到你在“i”循环中,而不是在“d”循环中:因为你减少了频率:)
if (current++ % onePercent == 0)
{
int percent = Convert.ToInt32(((decimal)current / (decimal)max) * 100);
this._worker.ReportProgress(percent, new WorkerUserState { current = current, max = max });
}