后台工作人员冻结WPF [英] backgroundworker freeze WPF

查看:65
本文介绍了后台工作人员冻结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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆