Can't get my head around background workers in .NET

Posted by Connel on Stack Overflow See other posts from Stack Overflow or by Connel
Published on 2010-04-09T12:57:01Z Indexed on 2010/04/09 15:03 UTC
Read the original article Hit count: 340

Filed under:
|
|

I have wrote an application that syncs two folders together. The problem with the program is that it stops responding whilst copying files. A quick search of stack-overflow told me I need to use something called a background worker. I have read a few pages on the net about this but find it really hard to understand as I'm pretty new to programming. Below is the code for my application - how can I simply put all of the File.Copy(....) commands into their own background worker (if that's even how it works)? Below is the code for the button click event that runs the sub procedure and the sub procedure I wish to use a background worker on all the File.Copy lines.

Button event:

protected virtual void OnBtnSyncClicked (object sender, System.EventArgs e)
{   
    //sets running boolean to true
    booRunning=true;

    //sets progress bar to 0
    prgProgressBar.Fraction = 0;

    //resets values used by progressbar
    dblCurrentStatus = 0;
    dblFolderSize = 0;  

    //tests if user has entered the same folder for both target and destination
    if (fchDestination.CurrentFolder == fchTarget.CurrentFolder) {
        //creates message box
        MessageDialog msdSame = new MessageDialog(this, DialogFlags.Modal, MessageType.Error, ButtonsType.Close, "You cannot sync two folders that are the same");
        //sets message box title
        msdSame.Title="Error";          
        //sets respone type
        ResponseType response = (ResponseType) msdSame.Run();
        //if user clicks on close button or closes window then close message box
        if (response == ResponseType.Close || response == ResponseType.DeleteEvent) {
            msdSame.Destroy();
        }
        return;
    }

    //tests if user has entered a target folder that is an extension of the destination folder
    // or if user has entered a desatination folder that is an extension of the target folder
    if (fchTarget.CurrentFolder.StartsWith(fchDestination.CurrentFolder) || fchDestination.CurrentFolder.StartsWith(fchTarget.CurrentFolder)) {
        //creates message box
        MessageDialog msdContains = new MessageDialog(this, DialogFlags.Modal, MessageType.Error, ButtonsType.Close, "You cannot sync a folder with one of its parent folders");
        //sets message box title
        msdContains.Title="Error";          
        //sets respone type and runs message box
        ResponseType response = (ResponseType) msdContains.Run();
        //if user clicks on close button or closes window then close message box
        if (response == ResponseType.Close || response == ResponseType.DeleteEvent) {
            msdContains.Destroy();
        }
        return;
    }
    //gets folder size of target folder
    FileSizeOfTarget(fchTarget.CurrentFolder);
    //gets folder size of destination folder
    FileSizeOfDestination(fchDestination.CurrentFolder);
    //runs SyncTarget procedure
    SyncTarget(fchTarget.CurrentFolder);
    //runs SyncDestination procedure
    SyncDestination(fchDestination.CurrentFolder);
    //informs user process is complete
    prgProgressBar.Text = "Finished";
    //sets running bool to false
    booRunning = false;
}

Sync sub-procedure:

protected void SyncTarget (string strCurrentDirectory)
{
    //string array of all the directories in directory
    string[] staAllDirectories = Directory.GetDirectories(strCurrentDirectory);
    //string array of all the files in directory
    string[] staAllFiles = Directory.GetFiles(strCurrentDirectory);

    //loop over each file in directory
    foreach (string strFile in staAllFiles)
    {
        //string of just the file's name and not its path
        string strFileName = System.IO.Path.GetFileName(strFile);
        //string containing directory in target folder
        string strDirectoryInsideTarget = System.IO.Path.GetDirectoryName(strFile).Substring(fchTarget.CurrentFolder.Length);

        //inform user as to what file is being copied
        prgProgressBar.Text="Syncing " + strFile;

        //tests if file does not exist in destination folder
        if (!File.Exists(fchDestination.CurrentFolder + "/" + strDirectoryInsideTarget + "/" + strFileName)) {
            //if file does not exist copy it to destination folder, the true below means overwrite if file already exists
            File.Copy (strFile, fchDestination.CurrentFolder + "/" + strDirectoryInsideTarget + "/" + strFileName, true);
        }


        //tests if file does exist in destination folder
        if (File.Exists(fchDestination.CurrentFolder + "/" + strDirectoryInsideTarget + "/" + strFileName)) {
            //long (number) that contains date of last write time of target file
            long lngTargetFileDate = File.GetLastWriteTime(strFile).ToFileTime();
            //long (number) that contains date of last write time of destination file
            long lngDestinationFileDate = File.GetLastWriteTime(fchDestination.CurrentFolder + "/" + strDirectoryInsideTarget + "/" + strFileName).ToFileTime();

            //tests if target file is newer than destination file
            if (lngTargetFileDate > lngDestinationFileDate) {
                //if it is newer then copy file from target folder to destination folder
                File.Copy (strFile, fchDestination.CurrentFolder + "/" + strDirectoryInsideTarget + "/" + strFileName, true);
            }   
        }
        //gets current file size
        FileInfo FileSize = new FileInfo(strFile);
        //sets file's filesize to dblCurrentStatus and adds it to current total of files 
        dblCurrentStatus = dblCurrentStatus + FileSize.Length;
        double dblPercentage = dblCurrentStatus/dblFolderSize;
        prgProgressBar.Fraction = dblPercentage;
    }

    //loop over each folder in target folder
    foreach (string strDirectory in staAllDirectories)
    {
        //string containing directories inside target folder but not any higher directories
        string strDirectoryInsideTarget = strDirectory.Substring(fchTarget.CurrentFolder.Length);
        //tests if directory does not exist inside destination folder
        if (!Directory.Exists(fchDestination.CurrentFolder + "/" + strDirectoryInsideTarget)) {
            //it directory does not exisit create it
            Directory.CreateDirectory(fchDestination.CurrentFolder + "/" + strDirectoryInsideTarget);
        }
        //run sync on all files in directory
        SyncTarget(strDirectory);
    }

}

Any help will be greatly appreciated as after this the program will pretty much be finished :D

© Stack Overflow or respective owner

Related posts about backgroundworker

Related posts about mono