-2

Having a large sincronous code that use BinaryFormatter to serialize several tables how can i update progressbar ?

the code that perform serialization is :

 private void Serialize()
    {
        try
        {

            int numberTableProcessed = 0;

            txtBoxProcessing.Text += "Start ..." + DateTime.Now + Environment.NewLine;


            AGENTS agenti = new AGENTS();
            agenti.SelectAndSerializeAgenti(openedConn);
            string pathAgenti = @"C:\...AGENTS.bin";
            if (File.Exists(pathAgenti))
            {
                long size = new FileInfo(pathAgenti).Length;
                 txtBoxProcessing.Text += "Processed AGENTI - " + string.Format("byte: {0:n}", size) + Environment.NewLine;
            }
            numberTableProcessed++;
            UpdateProgressBar(numberTableProcessed);

            PRODUCT anaart = new PRODUCT();
            anaart.SelectAndSerializeAnaart(openedConn);
            string pathAnaart = @"C:\...PRODUCT.bin";
            if (File.Exists(pathAnaart))
            {
                long size = new FileInfo(pathAnaart).Length;
                 txtBoxProcessing.Text += "Processed PRODUCT - " + string.Format("byte: {0:n}", size) + Environment.NewLine;
            }
            numberTableProcessed++;
            UpdateProgressBar(numberTableProcessed);
            ...

}

the code that update the progressbar

private void UpdateProgressBar(int numberTableProcessed)
    {
        int numberTotalTables = 22;
        progressBar1.Value = (numberTableProcessed / numberTotalTables) * 100;
    }

Using the method UpdateProgressBar i not see progress...it becomes full green at the end because the code is running sincronous (i think)

how can update progressbar?

I try this based on Lucifer suggest

public Form1()
    {
        InitializeComponent();

        backgroundWorker1.DoWork += backgroundWorker1_DoWork;
    }

    public void PerformSerialize()
    {
        backgroundWorker1.RunWorkerAsync();
    }
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        Serialize();
    }

    private void btnSerializza_Click(object sender, EventArgs e)
    {
        //Serialize();
        PerformSerialize();
    }
    public void UpdateProgressBar(int numberTableProcessed)
    {
        if (this.IsHandleCreated)
        {
            if (this.InvokeRequired)
            {
                this.Invoke((MethodInvoker)delegate { UpdateProgressBar(numberTableProcessed); });
                return;
            }
            else
            {
                int numberTotalTables = 22;
                progressBar1.Value = (numberTableProcessed / numberTotalTables) * 100;
                progressBar1.Increment(numberTotalTables);
            }
        }
    }
MeJonata
  • 25
  • 1
  • 6
  • The most appropriate option would probably be to execute that `Serialize` method on a secondary thread and make `UpdateProgressBar` thread-safe, i.e. make it marshal a call to the UI thread. You might also be able to simply call `Refresh` on the `ProgressBar` after setting its `Value` but I'm not sure that that will work for that control in particular. – jmcilhinney May 18 '18 at 08:27
  • 2
    Try to change `(numberTableProcessed * 100) / numberTotalTables` You always get zero until it is "full" – Julo May 18 '18 at 08:28

1 Answers1

0

You need to perform the serialization task into another thread.

Explanation:

  1. Here you will first create a backgroundworker (global or local your choice).
  2. you will call PerformSerialize() from the place where you are calling serialize() as of now which will call bgworker_dowork which will initiate a separate thread.
  3. you need to change structure of your UpgradeProgress method structure as I have shown to make it thread safe(Read this).

here is sample code which may help you

BackgroundWorker backgroundWorker1 = new System.ComponentModel.BackgroundWorker();

public void UpdateProgressBar(int numberTableProcessed)
{
  if (this.IsHandleCreated)
  {
    if (this.InvokeRequired)
    {
        this.Invoke((MethodInvoker)delegate{UpdateProgressBar(numberTableProcessed);});
        return;
    }
    else
    {
        int numberTotalTables = 22;
        progressBar1.Value = (numberTableProcessed * 100) / numberTotalTables
    }
}

this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);

call this method from where you call serialize.

public void PerformSerialize()
{
  backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
     //call Serialize() method
}

working

Lucifer
  • 1,594
  • 2
  • 18
  • 32
  • i try your code and i place in the button form PerformSerialize but nothig happen. – MeJonata May 18 '18 at 09:03
  • @MeJonata please edit question & show what you tried in detail, did you place the serialize method in background worker's code? – Lucifer May 18 '18 at 09:04
  • In my Button click (Serialize) i debug and when call PerformSerialize() nothig happen ...it return the form – MeJonata May 18 '18 at 09:23
  • you need to but breakpoint in backgroundWorker1_DoWork() as such it is other thread – Lucifer May 18 '18 at 09:24
  • ok in debug i get exception:Operazione cross-thread non valida: è stato eseguito l'accesso al controllo 'txtBoxProcessing' da un thread diverso da quello da cui è stata eseguita la creazione. – MeJonata May 18 '18 at 09:26
  • ok it was the textbox. tks it seems to work but now if i want a textbox to summarize the process where i have to code? – MeJonata May 18 '18 at 09:33
  • do it into the button click code before calling perform serialize,and also if this answer solves your problem then mark it as correct – Lucifer May 18 '18 at 09:41
  • tks but i need to understand multithread programming...:) bye – MeJonata May 18 '18 at 09:58
  • @MeJonata you may want to try this link - > https://www.tutorialspoint.com/csharp/csharp_multithreading.htm – Lucifer May 18 '18 at 10:00