后台工作人员冻结WPF [英] backgroundworker freeze WPF
问题描述
关注 BackgroundWorker
有什么问题?如果我尝试设置一些断点.. bw_ProgressChanged
的值已更新,但是如果我全部运行,则我的WPF为冻结"
What is wrong with following BackgroundWorker
?
If i try to set some breakpoints..the value of bw_ProgressChanged
is updated, but If i'm running all, my WPF is "Freeze"
public MainWindow()
{
InitializeComponent();
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
}
private readonly BackgroundWorker bw = new BackgroundWorker();
private void btnStart_Click(object sender, RoutedEventArgs e)
{
if (!bw.IsBusy)
{
bw.DoWork += bw_DoWork;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerAsync();
}
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.lblProgress.Content= e.ProgressPercentage.ToString()+ "%";
this.pb.Value = e.ProgressPercentage;
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
lblProgress.Content = "Cancel !";
else if (e.Error!=null)
lblProgress.Content= "Error: " + e.Error.Message;
else
lblProgress.Content = "Finish !";
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bw = sender as BackgroundWorker;
StreamReader sr = new StreamReader("C:\\File 1.txt");
StreamWriter sw = new StreamWriter("C:\\Out-File 1.txt");
var fi = new FileInfo("C:\\File 1.txt");
long total = (char)fi.Length;
int i = 0;
string result;
while (!sr.EndOfStream)
{
if (!bw.CancellationPending)
{
result = sr.ReadLine();
sw.WriteLine(result);
i = i + (char)result.Length;
bw.ReportProgress((int)((decimal)i / (decimal)total * (decimal)100));
}
else
{e.Cancel = true; break;}
} sw.Close(); sr.Close();
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
if (bw.WorkerSupportsCancellation)
bw.CancelAsync();
}
}
推荐答案
我知道这不是有关后台工作者问题的真正答案,但是也许是时候使用称为 async的新" C#5.0功能了/await ?我对您的代码进行了一些修改,并对其进行了测试,所有工作都没有错误和死机:
I know that it isn't really the answer on the question about background worker but maybe it's time to use "new" C# 5.0 feauture called async/await? I made some modifications in your code and tested it and all works without errors and freezes:
private bool cancelled;
private bool started;
public MainWindow()
{
InitializeComponent();
}
private async void btnStart_Click(object sender, RoutedEventArgs e)
{
if (started) return;
cancelled = false;
started = true;
try
{
await DoAsync();
}
catch (Exception exception)
{
lblProgress.Content = "Error: " + exception.Message;
return;
}
finally
{
started = false;
}
lblProgress.Content = cancelled ? "Cancel !" : "Finish !";
}
private async Task DoAsync()
{
using (var sr = new StreamReader("C:\\File 1.txt"))
{
using (var sw = new StreamWriter("C:\\Out-File 1.txt"))
{
var fi = new FileInfo("C:\\File 1.txt");
long total = (char) fi.Length;
int i = 0;
string result;
while (!sr.EndOfStream)
{
result = await sr.ReadLineAsync();
await sw.WriteLineAsync(result);
i = i + (char) result.Length;
ProgressChanged((int) ((decimal) i/(decimal) total*(decimal) 100));
if (cancelled) return;
}
}
}
}
private void ProgressChanged(int progress)
{
this.lblProgress.Content = progress.ToString() + "%";
this.pb.Value = progress;
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
cancelled = true;
}
我对百分比计算的建议是检查它在每次迭代中是否都已更改,然后增加接口更新.
Also my advice about percent calculation is to check if it's changed in each iteration and then rise interface updates.
这篇关于后台工作人员冻结WPF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!