Using BackgroundWorker in an object and updating the user interface

Edit: Been somewhere, hopefully

Here is what I have, but I'm not so sure about how I delegate my bcLoad.ReportProgress (i) to the created object (that is, how to make the delegate so that it can be transferred). I created object events that work (I can call the method of the object, and I see a change caused by reading in rows). I know when objectChanged works (written in the console). However, bcLoad_RunWorkerCompleted does not work, the code in the if statement is never executed, so I am mistaken somewhere. The file is loading, though.

Can someone please indicate how to create a delegate, then which section to use the delegate pass in (I assume in the object) and why bcLoad_RunWorkerComplete is NULL. This is really the first time I have used events, delegates and background workers in C #

/*
The object which does file operations
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
using System.Windows.Forms;
using System.ComponentModel;
using System.Data;

namespace aodProductionViewer
{
    public class fileOperationsSpecial
    {
        public event EventHandler Changed;

        protected virtual void OnChanged(EventArgs e)
        {
            if (Changed != null)
            {
                Changed(this, e);
            }
        }

        public fileOperationsSpecial() 
        {        }

        /// <summary>
        /// Count the number of lines in the file specified.
        /// </summary>
        /// <param name="f">The filename to count lines in.</param>
        /// <returns>The number of lines in the file.</returns>
        static long CountLinesInFile(string f)
        {
            long count = 0;
            try
            {
                using (StreamReader r = new StreamReader(f))
                {
                    string line;
                    while ((line = r.ReadLine()) != null)
                    {
                        count++;
                    }
                }
            }
            catch (Exception err)
            {
                string strTemp = "Error get number of lines for save game file. \n" +
                                err.ToString();
                errorDialog errDiag = new errorDialog("save game line count",
                                        strTemp, true);
            }
            return count;
        }

        /// <summary>
        /// Use this to readin in a file
        /// </summary>
        /// <param name="strPath">Path of file to read in</param>
        /// <returns>a string array of the file</returns>
        public string[] readFile(string strPath)
        {
            long lng_LineCount = CountLinesInFile(strPath);
            string[] strReadIn = new string[lng_LineCount];
            try
            {
                long lngCount = 0;
                using (StreamReader reader = new StreamReader(strPath))
                {
                    String line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        strReadIn[lngCount] = line;
                        lngCount++;
                        OnChanged(EventArgs.Empty);
                    }
                }

            }
            catch (Exception err)
            { //            
            }

            return strReadIn;
        }
   }
}

/*
Event Listner
*/
using System;
using System.Collections.Generic;
using System.Text;

namespace aodProductionViewer
{
    class EventListener
    {
        private fileOperationsSpecial FPS;

        public EventListener(fileOperationsSpecial _fps)
        {
            FPS = _fps;
            FPS.Changed += new EventHandler(objectChanged);
        }

        private void objectChanged(object sender, EventArgs e)
        {            //changed has occured
        }

        public void Detach()
        {
            FPS.Changed -= new EventHandler(objectChanged);
            FPS = null;
        }
    }
}

/*
The backgroundWorker code (Part of)
*/

    BackgroundWorker bcLoad = new BackgroundWorker();

    private void btt_load_save_game_Click(object sender, EventArgs e)
    {
        //Do some file dialog stuff
        string strPath = null;
        bcLoad.RunWorkerAsync(strPath);
    }

    void bcLoad_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        tb_ProgressBar.Value = e.ProgressPercentage;
    }

    void bcLoad_DoWork(object sender, DoWorkEventArgs e)
    {
        string strPath = e.Argument as string;
        fileOperationsSpecial FPS = new fileOperationsSpecial();
        EventListener listener = new EventListener(FPS);
        string strArray = FPS.readFile(strPath);
        listener.Detach();
    }

    void bcLoad_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Result != null)
        {
            //Everything done
            tb_ProgressBar.Visible = false;
        }
    }

I have a reason to use BackgroundWorker to do some work and update the user interface for progress and completion, I have something simple at the moment. As you can see, I pass the line (this is the way) Then I would read the file and update the progress, currently I just sleep the stream and set the progress for demonstration. I also intend to return the object (a string array), but I have not been able to do this yet.

: , , ? , (, , , ).

, , a > BackgroundWorker > .

,

a > > BackgroundWorker > a >

, , , . ? , .

, , !

( , )

BackgroundWorker bcLoad = new BackgroundWorker();

    public frm_ProductionViewer()
    {
        InitializeComponent();
        load_settings();
        bcLoad.DoWork += new DoWorkEventHandler(bcLoad_DoWork);
        bcLoad.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bcLoad_RunWorkerCompleted);

        bcLoad.WorkerReportsProgress = true;
        bcLoad.ProgressChanged += new ProgressChangedEventHandler(bcLoad_ProgressChanged);

        bcLoad.WorkerSupportsCancellation = true;
    }

private void btt_load_save_game_Click(object sender, EventArgs e)
    {

        ts_label_GameLoaded.Text = "Loading";
        bcLoad.RunWorkerAsync(strPath);
    }

void bcLoad_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        tb_ProgressBar.Value = e.ProgressPercentage;
    }

    void bcLoad_DoWork(object sender, DoWorkEventArgs e)
    {
            string strPath = e.Argument as string;
            //load file
            //Update progress
            bcLoad.ReportProgress(80);
            Thread.Sleep(300 * 5);
            bcLoad.ReportProgress(100);
    }

    void bcLoad_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Result != null)
        {
            textBox1.Text = "done";
        }
        tb_ProgressBar.Visible = false; ;
        ts_label_GameLoaded.Text = "Loaded";
    }
+3
2

( ) GUI, Bgw.

, Bgw () DoWork.

, ( , ).

( ) bcLoad.ReportProgress(percent).


Edit:

  • EventArgs , EventHandler<ProgressEventArgs>, , , ProgressEventArgs.

  • , EventListener. . :

 

class Form ...
{
    private void objectChanged(object sender, ProgressEventArgs e)
    {   //changed has occured
        // trigger the Bgw event
        // or use Form.Invoke here to set the progress directly
        bcLoad.ReportProgress(e.Percentage);          
    }

}

, "" 2 . 1, FPS, 1 .

+3

, ( ) , :

  • X ""
  • X ""
  • X " "
  • X , Done, , .
0

Source: https://habr.com/ru/post/1757386/


All Articles