【问题标题】:Update UI Progress bar from external method从外部方法更新 UI 进度条
【发布时间】:2013-10-25 09:37:52
【问题描述】:

所以这是我第一次尝试使用委托、事件、Backgroundworkers、WPF...几乎所有东西都是新的。我有一个运行长时间运行的方法的外部类,我想报告进度:

public class ShortFileCreator
{
    public void CreateShortUrlFile(string outputfilepath)
    {         
        foreach(string line in lines)
        {
                //work work work processing file
                if (ReportProgress != null)
                {
                //report progress that a file has been processed
                    ReportProgress(this, new ProgressArgs {TotalProcessed = numberofurlsprocessed
                                                         , TotalRecords = _bitlyFile.NumberOfRecords});
                }
        }
    }

    public delegate void ReportProgressEventHandler (object sender, ProgressArgs args);

    public event ReportProgressEventHandler ReportProgress;

    public class ProgressArgs : EventArgs
    {
        public int TotalProcessed { get; set; }
        public int TotalRecords { get; set; }
    }
}

在我的 WPF 表单中,我想启动 CreateShortUrlFile 方法并更新表单的进度条。

private void btnRun_Click(object sender, RoutedEventArgs e)
    {
       var shortFileCreator = new ShortFileCreator();           

        _worker = new BackgroundWorker
        {
            WorkerReportsProgress = true,
            WorkerSupportsCancellation = true
        };

        shortFileCreator.ReportProgress += ShortFileCreator_ReportProgress;

        _worker.DoWork += delegate(object s, DoWorkEventArgs args)
        {
            _bitlyFileWorker.CreateShortUrlFile(saveFileDialog.FileName);
        };

        _worker.RunWorkerAsync();
    }

    protected void ShortFileCreator_ReportProgress(object sender, ShortFileCreator.ProgressArgs e)
    {
        //update progress bar label
        txtProgress.Content = String.Format("{0} of {1} Records Processed", e.TotalProcessed, e.TotalRecords);
        //update progress bar value
        progress.Value = (double) e.TotalProcessed/e.TotalRecords;
    }

但是,当我运行它时,它会处理一行,然后出现异常:调用线程无法访问此对象,因为另一个线程拥有它。什么其他线程拥有这个? ReportProgress 事件不应该将 ProgressArgs 返回给任何订阅者吗?

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    这是因为像 ProgressBarTextBox 这样的 UI 控件不能被另一个线程触及,在这种情况下,您正在尝试从 BackgroundWorker 线程更新它们。

    解决此问题的方法是通过Invoke 回调 UI 线程,您可以使用 Dispatcher 执行此操作

    protected void ShortFileCreator_ReportProgress(object sender, ShortFileCreator.ProgressArgs e)
    {
        Dispatcher.Invoke((Action)delegate
        {
           //update progress bar label
           txtProgress.Content = String.Format("{0} of {1} Records Processed", e.TotalProcessed, e.TotalRecords);
           //update progress bar value
           progress.Value = (double) e.TotalProcessed/e.TotalRecords;
        });
    }
    

    【讨论】:

    • 完美运行。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多