Using MySqlBackup.NET with Progress Bar from C# to VB .Net

Jan 22, 2013 at 7:03 AM

hi.

i tried to use mysqlbackup.dll to my VB.Net project.

and i stuck to use it with Progress Bar control.

from C# to VB.Net code, how to use it.

i tried to edit all of the code from

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        // Temporary Storage Location
        string CurrentTableName = "";
        long TotalRowsInCurrentTable = 0;
        long TotalRowsInAllTables = 0;
        long CurrentRowInCurrentTable = 0;
        long CurrentRowInAllTable = 0;
        int TotalTables = 0;
        int CurrentTableIndex = 0;
        int PercentageComplete = 0;
        int PercentageGetTotalRowsCompleted = 0;

        MySqlBackup mb;

        Timer timerRead;
        Timer timerStop;

        bool stopTimer1 = false;

        public Form1()
        {
            InitializeComponent();
        }
    }
}

to VB.Net Syntax.

Please i need advice. :)

Coordinator
Jan 22, 2013 at 7:11 AM
Edited Jan 22, 2013 at 7:12 AM

I'm am beginner of VB.NET not much can guide you on writing in VB.NET,

but however, you can use a lots of C# to VB.NET converter. They can be easily found in search engine(i.e. google)

there is a user posted a question about events and delegate of VB.NET in stackoverflow.com
You may have a look at: Delegate Error when converting C# to VBNET

Jan 22, 2013 at 7:28 AM

thank you sir for reply me.

i use converter now. thank you,

but i found some problem again with this section.

public Form1()
{
    InitializeComponent();
    timerRead = new Timer();
    timerRead.Interval = 100; // Refresh Progress Bar 10 times in 1 second
    timerRead.Tick += new EventHandler(timerRead_Tick);
}

the BOLD row, in my VB.Net Project there is no timerRead.Tick ?

Coordinator
Jan 22, 2013 at 7:32 AM
Edited Jan 22, 2013 at 7:44 AM

Repeat for previous post:

there is a user posted a question about events and delegate of VB.NET in stackoverflow.com
You may have a look at: Delegate Error when converting C# to VBNET

The above link explained how to handle this:

 "timerRead.Tick += new EventHandler(timerRead_Tick);"

in VB.NET

Jan 22, 2013 at 8:06 AM

oh yea,

i solved it sir.

thank you.

once again ,

about this code

Private Sub timerRead_Tick(ByVal sender As Object, ByVal e As EventArgs)
        progressBar_PercentComplete.Maximum = 100
        progressBar_PercentComplete.Value = PercentageComplete
        progressBar_Table.Maximum = TotalTables * 10
        progressBar_Table.Value = CurrentTableIndex * 10
        progressBar_RowsDB.Maximum = CInt(TotalRowsInAllTables)
        progressBar_RowsDB.Value = CInt(CurrentRowInAllTable)
        progressBar_RowsTable.Maximum = CInt(TotalRowsInCurrentTable)
        progressBar_RowsTable.Value = CInt(CurrentRowInCurrentTable)
End Sub

is it a control of a progress Bar ?

Coordinator
Jan 22, 2013 at 9:16 AM
Edited Jan 22, 2013 at 9:16 AM

yes it is.

Coordinator
Jan 22, 2013 at 9:20 AM
Edited Jan 22, 2013 at 9:22 AM

As fas as I know, Niemand and crayzyivan (team members of this project) are VB.NET programmers .

You may request help from them or send a message to invite them to join the discussion.

Jan 22, 2013 at 1:33 PM
Edited Jan 22, 2013 at 1:40 PM

Okay sir, i Invited Niemand to join our discussion here.

as far i know sir,

in here code

void timerRead_Tick(object sender, EventArgs e)
{
    progressBar_PercentComplete.Maximum = 100;
    progressBar_PercentComplete.Value = PercentageComplete;

    progressBar_Table.Maximum = TotalTables * 10;
    progressBar_Table.Value = CurrentTableIndex * 10;

    progressBar_RowsDB.Maximum = (int)TotalRowsInAllTables;
    progressBar_RowsDB.Value = (int)CurrentRowInAllTable;

    progressBar_RowsTable.Maximum = (int)TotalRowsInCurrentTable;
    progressBar_RowsTable.Value = (int)CurrentRowInCurrentTable;
}
there is a progress bar control.
where you declare the progressBar ?
because in my VB.Net Project , I really need to declare it first.
Coordinator
Jan 22, 2013 at 2:48 PM

It is declared in the designer.

Once you drag and drop a Progress bar in the form,

you can directly use it in code behind.

        ProgressBar1.Maximum = 100

        For i As Integer = 0 To 99
            ProgressBar1.Value = (i + 1)
        Next

Jan 23, 2013 at 8:20 AM

i did, drag and drop the progressbar1 to my form project.

but i not declared yet,

im really don't know how it works.

and i try to use this code

        ProgressBar1.Maximum = 100

        For i As Integer = 0 To 99
            ProgressBar1.Value = (i + 1)
        Next
in my timerread_tick sub

Private Sub timerRead_Tick(ByVal sender As Object, ByVal e As EventArgs)
        For i As Integer = 0 To 99
            ProgressBar1.Value = (i + 1)
        Next
        'ProgressBar_PercentComplete.Maximum = 100
        'progressBar_PercentComplete.Value = PercentageComplete
        '    progressBar_Table.Maximum = TotalTables * 10
        '    progressBar_Table.Value = CurrentTableIndex * 10
        '    progressBar_RowsDB.Maximum = CInt(TotalRowsInAllTables)
        '    progressBar_RowsDB.Value = CInt(CurrentRowInAllTable)
        '    progressBar_RowsTable.Maximum = CInt(TotalRowsInCurrentTable)
        '    progressBar_RowsTable.Value = CInt(CurrentRowInCurrentTable)
 End Sub

it don't work either.
please any solution sir?
Coordinator
Jan 23, 2013 at 10:20 AM
rsanzz wrote:

i did, drag and drop the progressbar1 to my form project.

but i not declared yet,

when you drag n drop the progressbar1

VB.NET help you to declared it automatically in code behind

Jan 23, 2013 at 11:37 AM

yea i got it

this is the code behind the form designer

'ProgressBar1
        '
        Me.ProgressBar1.Location = New System.Drawing.Point(176, 184)
        Me.ProgressBar1.Name = "ProgressBar1"
        Me.ProgressBar1.Size = New System.Drawing.Size(174, 23)
        Me.ProgressBar1.TabIndex = 2

.

and it declared name as ProgressBar1

in your code project is

ProgressBar_PercentComplete.Maximum = 100
progressBar_PercentComplete.Value = PercentageComplete
progressBar_Table.Maximum = TotalTables * 10

i don't know how to use the code with the correct syntax in VB. Net
Coordinator
Jan 23, 2013 at 11:57 AM
Edited Jan 23, 2013 at 11:59 AM

Hi, I have built (with the help of C# to VB.NET converter) :) 

and uploaded a sample project of VB.NET at here: http://mysqlbackupnet.codeplex.com/releases

 

ProgressBar_PercentComplete
progressBar_PercentComplete
progressBar_Table

these are just the name of the component. You can name it anything.

when you drag n drop ProgressBar into your WinForm, VB.NET will automatically give it a name for you.

By default, if you drag n drop 4 ProgressBar, the names will be

  • ProgressBar1
  • ProgressBar2
  • ProgressBar3
  • ProgressBar4

You can change the name of the component at the Properties Explorer of the components.

Coordinator
Jan 23, 2013 at 1:13 PM

I have started converting demo project to VB and noticed some memory leaks in both C# and VB frmMainDemo

You declare timers and MySqlBackup objects as private in form class (in VB they need to be declared WithEvents). Then you create new instances of these objects and add adequate handlers to them every time an operation is started. But you never remove handlers which leads to keeping every instance in memory after they are done.

I believe the right way should be not to have form scope private variables, remove handlers  and dispose instances in appropriate "ending events".

However in order not to make too many modifications I use helper method before each (re)creation of an object that checks if the object has handlers to remove and removes them.

Coordinator
Jan 23, 2013 at 1:29 PM

Actually why timers are used at all? Why not update labels in progress changed event handlers?

Coordinator
Jan 23, 2013 at 1:53 PM

Why do you use a file to safe the connstring? Why not application settings?

Besides a program frequently has no write privilege in CurrentDirectory (usually Program Files, but might be also system32, CurrentDirectory != exe location). Use Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) instead or application settings.

 

Coordinator
Jan 23, 2013 at 3:20 PM

 

EncryptSqlDumpFile with 35M file didn't end within 5 min.

Coordinator
Jan 23, 2013 at 4:36 PM

Uploaded demo project converted to VB in issue tracker.

Some test forms use mysql connections in a insecure  manner. Closing of connections should always happen in finally section or try...catch block. Didn't have patience to fix it.

Coordinator
Jan 24, 2013 at 1:48 AM
Edited Jan 24, 2013 at 2:09 AM

thanks you very much for converting the C# Demo into VB.NET and the memory leak fixes. I have uploaded/included the VB demo app into Download, and it will remain available throughout future releases. and it will be included in source control too.

Issue: events handlers created every time the process is executed in demo form.

yes, I agree with that. this is not good and this shall be fixed. the event shall be created just once when the form is initialized and started up.

Issue: using timer vs progress changed event handlers

Assume that MySqlBackup.NET is run in Synchronous Mode, ProgressChanged event will raise about more than 1000 times in a second, which might cause a winform's progressbar to draw/refresh thousand times in 1 second. The whole process will become very slow, mysqlbackup will have to wait UI to finish redraw/refresh. this is because winform refresh rate isn't that fast. unless the winform is using directX or gdi+ to help in redrawing/refreshing the UI. However, in synchronous mode, ProgressChanged event is disable by default in MySqlBackup.NET.

I make a test on this which uses ProgressChanged event to refresh WinForm UI directly (in asynchronous mode) and an exception raised:

System.InvalidOperationException was unhandled by user code
  Message=Cross-thread operation not valid: Control 'lbPercentage' accessed from a thread other than the thread it was created on.
  Source=System.Windows.Forms
  StackTrace:
       at System.Windows.Forms.Control.get_Handle()
       at System.Windows.Forms.Control.set_WindowText(String value)
       at System.Windows.Forms.Control.set_Text(String value)
       at System.Windows.Forms.Label.set_Text(String value)
       at MySqlBackupDemo.frmMainDemo.mb_ExportProgressChanged(Object sender, ExportProgressArg e) in D:\test\MySqlBackupDemo\frmMainDemo.cs:line 280
       at MySql.Data.MySqlClient.MySqlBackup.ExportExecute() in D:\test\MySqlBackup.NET\MySqlBackup.cs:line 285
       at MySql.Data.MySqlClient.MySqlBackup.bwExport_DoWork(Object sender, DoWorkEventArgs e) in D:\test\MySqlBackup.NET\MySqlBackup.cs:line 252
       at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
       at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
  InnerException: 

Guess that, the UI controls is managed by another thread which different from MySqlBackup. MySqlBackup is using it's own separate thread.

Issue: Saving Connection String in File vs Application Settings

Is there any difference? or is it because of security impact?

I'm thinking that this is just a demo app. The programmers can save it anywhere they like. About Environment.CurrentDirectory, this might not suitable as you said.

Perhaps this Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) or Application.StartupPath.is more suitable  This will be fixed.

Issue: EncryptSqlDumpFile with 35M file didn't end within 5 min

How much time do it takes? I am thinking of simplifies the encryption process. remove certain method to make it less time consuming. I'll study this in the next release.

Issue: MySql Connection is not closed properly in some section in Demo App.

Will fix it in next release.

Coordinator
Jan 24, 2013 at 2:02 AM

Demo App of VB.NET is added / uploaded into source control.

Jan 24, 2013 at 8:39 AM

thank you adriancs to make a sample in VB.Net

it's so help me out.

but i want to ask you, when i try to make same form as you sample.

an error shown

Private Sub ButtonX1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonX1.Click
        Dim sf As New SaveFileDialog()
        sf.FileName = "test " + DateTime.Now.ToString("yyyyMMdd HHmmss") + ".sql"
        If sf.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then
            Return
        End If
        ProgressBar1.Value = 0
        TimerRead.Start()
        Dim constr As String = "server=localhost;user=root;database=gofun;"
        mb.Connection = New MySqlConnection(constr)
        mb.ExportInfo.FileName = sf.FileName
        mb.ExportInfo.AsynchronousMode = False
        mb.ExportInfo.ExportTableStructure = True
        mb.ExportInfo.ExportRows = True
        mb.Export()
    End Sub

 

the error code is The given key was not present in the dictionary.

the error is refer to mb.export() 

the error shown caused when i set the mb.exportinfo.exportRows to True and exportTableStructure to True .

if it's false, the backup file doesn't contain anything.

sample .sql file when the mb.exportinfo.exportRows = false and mb.ExportInfo.ExportTableStructure = false


-- MySqlBackup.NET dump 1.5.6 beta
-- Dump time: 2013-01-24 16:32:02
-- ------------------------------------------------------
-- Server version    5.0.51b-community-nt-log MySQL Community Edition (GPL)


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VA

Coordinator
Jan 24, 2013 at 11:56 AM

I have uploaded/included the VB demo app into Download, and it will remain available throughout future releases. and it will be included in source control too.

Did you notice that my project is saved by VS 2005? You use higher version of VS. Maybe it would be wise to upgrade VB project so that all the projects are of the same VS version?

 the event shall be created just once when the form is initialized and started up

Not necessarily, e.g.  if an object keeps a connection open during its lifetime, it would be reasonable not to bind a lifetime of such an object with the lifetime of the containing winform...

What is really necessary is not to forget to remove handlers so that the object could be properly disposed (which only happens when there is no link left between the containing form and an object).

Assume that MySqlBackup.NET is run in Synchronous Mode, ProgressChanged event will raise about more than 1000 times in a second, which might cause a winform's progressbar to draw/refresh thousand times in 1 second. The whole process will become very slow

You're right. Tested with ~35MB dump size database: with timers ~17 sec., without  ~3 min. 30 sec.

It demonstrates that the progress reporting within MySqlBackup object should be improved. Just not sure how exactly:

- to use switch to reporting extent (Short/Full);

- to implement  some clever algorithms to exclude extremely short operations from the reporting scope;

- to implement timer pattern within  MySqlBackup object, etc.

I make a test on this which uses ProgressChanged event to refresh WinForm UI directly (in asynchronous mode) and an exception raised: f

It's because your implementation of backgroundworker within MySqlBackup is faulty. Method Do_work should never interact with the original object/data, deep copy of the object should be passed as an argument to BackGroundWorker. All data transfers (incl. progress reporting) should be done by appropriate BackgroundWorker events exclusively.

I worked around the flaws by implementing delegate invoke pattern in winform. But it is not an elegant solution.

The point is: if you implement threading within your object you should also encapsulate it fully. "User  code" (gui, etc.) should never care about the objects internals.

The programmers can save it anywhere they like.

 OS (e.g. win vista) would strongly oppose that :)

In many scenarios windows wouldn't allow a program to save anything to its Program Files folder (~ Application.StartupPath). Which would cause unhandled security exceptions and hinder functionality. Environment.SpecialFolder.ApplicationData points to a sort of sandbox for the application where it can do (mostly) whatever it likes.

 If you provide some demo, it shouldn't contain examples of faulty methods.

 EncryptSqlDumpFile with 35M file How much time do it takes?

 Don't know. Started the process, went to have a smoke, got back, it was still running, stopped it in order to continue coding.

Jan 24, 2013 at 12:00 PM
Edited Jan 24, 2013 at 12:06 PM

i just downloaded the new one sample.

its look awesome.

let me take a look. :)

 

--------

i use vs 2005,

and the project works!

its awesome.

Thank you Niemand and Adriancs. this is a great project.

Coordinator
Jan 24, 2013 at 1:50 PM

Hi, rsanzz,

there is a bug. ^^

when ExportInfo.AsynchronousMode = true and ExportInfo.CalculateTotalRowsFromDatabase = false 

at the same time, the error that you've mentioned will occur.

Most of us did not see this error, because, 

when we use ExportInfo.AsynchronousMode = true and this ExportInfo.CalculateTotalRowsFromDatabase will sure = true

and if we use ExportInfo.AsynchronousMode = false and this ExportInfo.CalculateTotalRowsFromDatabase will sure = false

 

I have fixed it in V1.5.7.

but the memory leak in Full Demo of C# Project is not fixed yet.

You can download the newly baked MySqlBackup.NET about 30 minutes ago. 

happy coding ^^

Coordinator
Jan 24, 2013 at 11:16 PM
Edited Jan 24, 2013 at 11:17 PM

To Niemand:

with timers ~17 sec., without  ~3 min. 30 sec

This is very fast. what type of processor, hard disk and memory(amount) you are using?

 

and for the rest of the suggestion or proposed work out, are listed here: Next - To Do List

Coordinator
Jan 25, 2013 at 9:06 AM

Intel core2 duo 2GHz, 4GB RAM, DELL XPS, not sure about HDD