进度条未使用 BackgroundWorker 更新
Progress Bar not updating using BackgroundWorker
我正在尝试读取文件并在屏幕上显示进度。
它应该显示在 Progress Bar(进度)和文本框(progress_text)上。
这是我正在使用的代码:
public partial class MainWindow : Window
{
public static List<String> file = new List<String>();
public long currentPosition = 0;
String line;
long length;
public BackgroundWorker worker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
worker.WorkerReportsProgress = true;
worker.DoWork += worker_DoWork;
worker.ProgressChanged += worker_ProgressChanged;
}
private void Start(object sender, RoutedEventArgs e)
{
worker.RunWorkerAsync();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bg = sender as BackgroundWorker;
Dispatcher.Invoke(() =>
{
progress.Minimum = 0;
progress.Maximum = 100;
FileInfo fi = new FileInfo(upload.Text);
length = fi.Length;
int percent;
using (StreamReader sr = new StreamReader(upload.Text, System.Text.Encoding.ASCII))
{
while (sr.EndOfStream == false)
{
line = sr.ReadLine();
file.Add(line);
currentPosition += line.Count();
percent = (int)(100.0 / length * currentPosition);
bg.ReportProgress(percent);
}
}
});
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progress.Value = e.ProgressPercentage;
progress_text.Text = "reading " + currentPosition + " out of " + length;
}
}
XAML:
<Window x:Class="ProgressBarUploadFile.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20*"/>
<RowDefinition Height="20*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Content="Select File" FontSize="15" Click="Upload_file"/>
<TextBox x:Name="upload" Grid.Row="0" Grid.Column="1" Text="" />
<Button Grid.Row="1" Grid.Column="0" Content="Start upload" FontSize="15" Click="Start"/>
<ProgressBar Name="progress" Grid.Row="1" Grid.Column="1" />
<TextBlock Name="progress_text" Grid.Row="1" Grid.Column="1" VerticalAlignment="Bottom"/>
</Grid>
当我 运行 它处于调试状态时,它似乎可以正常工作。
但是进度条和文本框只有在文件完全读取后才会更新。
我遵循了一些教程,例如:
https://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx?f=255&MSPPError=-2147217396
http://www.wpf-tutorial.com/misc-controls/the-progressbar-control/
可是我想不通..
我觉得是个很小的东西,但是找不到。
谢谢!
试试这个代码:
private void Start(object sender, RoutedEventArgs e)
{
progress.Minimum = 0;
progress.Maximum = 100;
worker.RunWorkerAsync();
}
BackgroundWorker bg = sender as BackgroundWorker;
FileInfo fi = new FileInfo(@"File");
length = fi.Length;
int percent;
using (StreamReader sr = new StreamReader(@"File", System.Text.Encoding.ASCII))
{
while (sr.EndOfStream == false)
{
line = sr.ReadLine();
file.Add(line);
currentPosition += line.Count();
percent = (int)(currentPosition / length) * 100;
bg.ReportProgress(percent);
Thread.Sleep(100);
}
}
你的代码有这个问题:
(int)(a / b) * 100
会先计算出a/b
再转换成int
再转换成*100
,所以在a
到达b
之前, a/b
将始终为 0.*
,(int)(a/b)
将始终为 0
,因此最终值 0*100
将始终为 0。
突然当a=b
然后(int)(a/b)
变成1
最后的值变为100。这就是为什么你的进度条在文件被完全读取之前不会更新
所以,你应该使用 percent = (int)(currentPosition * 100 / length);
或@jmc 在评论中建议:使用percent = (int)(100.0 / length * currentPosition);
我正在尝试读取文件并在屏幕上显示进度。 它应该显示在 Progress Bar(进度)和文本框(progress_text)上。
这是我正在使用的代码:
public partial class MainWindow : Window
{
public static List<String> file = new List<String>();
public long currentPosition = 0;
String line;
long length;
public BackgroundWorker worker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
worker.WorkerReportsProgress = true;
worker.DoWork += worker_DoWork;
worker.ProgressChanged += worker_ProgressChanged;
}
private void Start(object sender, RoutedEventArgs e)
{
worker.RunWorkerAsync();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bg = sender as BackgroundWorker;
Dispatcher.Invoke(() =>
{
progress.Minimum = 0;
progress.Maximum = 100;
FileInfo fi = new FileInfo(upload.Text);
length = fi.Length;
int percent;
using (StreamReader sr = new StreamReader(upload.Text, System.Text.Encoding.ASCII))
{
while (sr.EndOfStream == false)
{
line = sr.ReadLine();
file.Add(line);
currentPosition += line.Count();
percent = (int)(100.0 / length * currentPosition);
bg.ReportProgress(percent);
}
}
});
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progress.Value = e.ProgressPercentage;
progress_text.Text = "reading " + currentPosition + " out of " + length;
}
}
XAML:
<Window x:Class="ProgressBarUploadFile.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20*"/>
<RowDefinition Height="20*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Content="Select File" FontSize="15" Click="Upload_file"/>
<TextBox x:Name="upload" Grid.Row="0" Grid.Column="1" Text="" />
<Button Grid.Row="1" Grid.Column="0" Content="Start upload" FontSize="15" Click="Start"/>
<ProgressBar Name="progress" Grid.Row="1" Grid.Column="1" />
<TextBlock Name="progress_text" Grid.Row="1" Grid.Column="1" VerticalAlignment="Bottom"/>
</Grid>
当我 运行 它处于调试状态时,它似乎可以正常工作。 但是进度条和文本框只有在文件完全读取后才会更新。
我遵循了一些教程,例如:
https://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx?f=255&MSPPError=-2147217396
http://www.wpf-tutorial.com/misc-controls/the-progressbar-control/
可是我想不通..
我觉得是个很小的东西,但是找不到。
谢谢!
试试这个代码:
private void Start(object sender, RoutedEventArgs e)
{
progress.Minimum = 0;
progress.Maximum = 100;
worker.RunWorkerAsync();
}
BackgroundWorker bg = sender as BackgroundWorker;
FileInfo fi = new FileInfo(@"File");
length = fi.Length;
int percent;
using (StreamReader sr = new StreamReader(@"File", System.Text.Encoding.ASCII))
{
while (sr.EndOfStream == false)
{
line = sr.ReadLine();
file.Add(line);
currentPosition += line.Count();
percent = (int)(currentPosition / length) * 100;
bg.ReportProgress(percent);
Thread.Sleep(100);
}
}
你的代码有这个问题:
(int)(a / b) * 100
会先计算出a/b
再转换成int
再转换成*100
,所以在a
到达b
之前, a/b
将始终为 0.*
,(int)(a/b)
将始终为 0
,因此最终值 0*100
将始终为 0。
突然当a=b
然后(int)(a/b)
变成1
最后的值变为100。这就是为什么你的进度条在文件被完全读取之前不会更新
所以,你应该使用 percent = (int)(currentPosition * 100 / length);
或@jmc 在评论中建议:使用percent = (int)(100.0 / length * currentPosition);