Update progress bar in MainWindow from a different Thread

前端 未结 2 1607
挽巷
挽巷 2021-01-01 08:17

I know this question has been asked several times an I spent all day trying to understand other answers, but since I am very new to C# and WPF nothing helped me so far. I wi

相关标签:
2条回答
  • 2021-01-01 08:40

    You can use Dispatcher.BeginInvoke() to push UI changes on the UI thread rather than worker thread. Most important thing - you need to access Dispatcher which is associated with UI thread not a worker thread you are creating manually. So I would suggest cache Dispatcher.Current and then use in a worker thread, you can do this via ParametersClass or just declaring a dispatchr field on a class level.

    public partial class MainWindow
    {
        private Dispatcher uiDispatcher;
    
        public MainWindow()
        {
            InitializeComponents();
    
            // cache and then use in worker thread method
            this.uiDispatcher = uiDispatcher;
        }
    
        public void MyLongCalculations(object myvalues)
        {
            ParameterObject values = (ParameterObject)myvalues;
            this.uiDispatcher.BeginInvoke(/*a calculations delegate*/);
        }
    }
    

    Also if you need to pass a UI dispatcher in some service/class (like ParametersClass) I would suggest take a look at this nice SO post which show how you can abstract it by an interfaces with ability to push UI changes synchronously/asynchronously so it would be up to a caller (basically use Invoke() or BeginInvoke() to queue a delegate in the UI messages pipeline).

    0 讨论(0)
  • 2021-01-01 08:51

    Background worker is well suited for this.

    try this:

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            // Initialize UI
            InitializeComponent();
    
            // Process data
            ProcessDataAsync(new ParameterClass { Value = 20 });
        }
    
        /// <summary>
        /// Processes data asynchronously
        /// </summary>
        /// <param name="myClass"></param>
        private void ProcessDataAsync(ParameterClass myClass)
        {
            // Background worker
            var myWorker = new BackgroundWorker
            {
                WorkerReportsProgress = true,
            };
    
            // Do Work
            myWorker.DoWork += delegate(object sender, DoWorkEventArgs e)
            {
                // Set result
                e.Result = MyLongCalculations(myClass);
    
                // Update progress (50 is just an example percent value out of 100)
                myWorker.ReportProgress(50);
            };
    
            // Progress Changed
            myWorker.ProgressChanged += delegate(object sender, ProgressChangedEventArgs e)
            {
                myProgressBar.Value = e.ProgressPercentage;
            };
    
            // Work has been completed
            myWorker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e)
            {
                // Work completed, you are back in the UI thread.
                TextBox1.Text = (int) e.Result;
            };
    
            // Run Worker
            myWorker.RunWorkerAsync();
        }
    
        /// <summary>
        /// Performs calculations
        /// </summary>
        /// <param name="myvalues"></param>
        /// <returns></returns>
        public int MyLongCalculations(ParameterClass myvalues)
        {
            //some calculations
            return (myvalues.Value*2);
        }
    
    }
    
    /// <summary>
    /// Custom class
    /// </summary>
    public class ParameterClass
    {
        public int Value { get; set; }
    }
    
    0 讨论(0)
提交回复
热议问题