Click here to Skip to main content
15,887,135 members
Home / Discussions / C#
   

C#

 
AnswerRe: JsonConvert.DeserializeObject Pin
James Curran11-Feb-21 23:58
James Curran11-Feb-21 23:58 
GeneralRe: JsonConvert.DeserializeObject Pin
Member 1449252212-Feb-21 7:08
Member 1449252212-Feb-21 7:08 
QuestionBackGroundWorker gives runtime error Pin
Alex Dunlop10-Feb-21 4:13
Alex Dunlop10-Feb-21 4:13 
AnswerRe: BackGroundWorker gives runtime error Pin
OriginalGriff10-Feb-21 4:36
mveOriginalGriff10-Feb-21 4:36 
GeneralRe: BackGroundWorker gives runtime error Pin
Alex Dunlop10-Feb-21 4:44
Alex Dunlop10-Feb-21 4:44 
GeneralRe: BackGroundWorker gives runtime error Pin
OriginalGriff10-Feb-21 5:00
mveOriginalGriff10-Feb-21 5:00 
GeneralRe: BackGroundWorker gives runtime error Pin
Alex Dunlop10-Feb-21 5:03
Alex Dunlop10-Feb-21 5:03 
GeneralRe: BackGroundWorker gives runtime error Pin
OriginalGriff10-Feb-21 5:43
mveOriginalGriff10-Feb-21 5:43 
No idea ... but I don't use the designer except for UI controls - BW isn't that, and I create them in code as needed. It's trivial to do.

Here's my code for the UI component of my file mover:
C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.IO;
using System.Data.SqlClient;
using BackgroundFileMove.UtilityCode;
using System.Windows.Forms;
using Microsoft.WindowsAPICodePack.Taskbar;
using System.Reflection;

namespace BackgroundFileMove
    {
    /// <summary>
    /// Background process - move the files
    /// </summary>
    public partial class frmMoveFilesInBackground : Form
        {
        #region Constants
        /// <summary>
        /// Block transfers allow us to do file progress reporting, and use less memory
        /// </summary>
        private const int blockSize = 8 * 1024 * 1024;
        #endregion

        #region Fields
        #region Internal
        /// <summary>
        /// When true, stops processing
        /// </summary>
        private volatile bool cancel = false;
        /// <summary>
        /// Delegate to call to do the move
        /// </summary>
        private FileMove.MoveFile moveDelegate;
        /// <summary>
        /// Delegate to call to do the DB update.
        /// </summary>
        private FileMove.UpdateDB updateDelegate;
        /// <summary>
        /// The files to move
        /// </summary>
        private IEnumerable<FileMove> files;
        /// <summary>
        /// Prompt for moving file
        /// </summary>
        private string moveFileAction;
        /// <summary>
        /// Prompt for updating after file move
        /// </summary>
        private string updateDBAction;
        /// <summary>
        /// Prompt for skipping file
        /// </summary>
        private string skippingAction;
        /// <summary>
        /// If true, form will close on completion.
        /// </summary>
        private bool closeOnDone;
        /// <summary>
        /// Block transfers allow us to do file progress reporting, and use less memory
        /// </summary>
        private byte[] transfer = new byte[blockSize];
        /// <summary>
        /// If true, copies the data instead of moving it.
        /// </summary>
        private bool doCopyOnly = false;
        #endregion

        #region Property bases
        #endregion
        #endregion

        #region Properties
        /// <summary>
        /// Gets a true value if the processing is going on.
        /// </summary>
        public bool IsProcessing { get { return butStop.Enabled; } }
        #endregion

        #region Regular Expressions
        #endregion

        #region Enums
        #endregion

        #region Classes
        /// <summary>
        /// Used internally for reporting progress into the display.
        /// </summary>
        private class ProgressReport
            {
            /// <summary>
            /// Name of file involved
            /// </summary>
            public string Filename { get; set; }
            /// <summary>
            /// Description of action taken
            /// </summary>
            public string Action { get; set; }
            /// <summary>
            /// File number in process order
            /// </summary>
            public int FileNumber { get; set; }
            /// <summary>
            /// Total number of files to be processed
            /// </summary>
            public int FilesCount { get; set; }
            /// <summary>
            /// Percentage of the file that has been moved.
            /// </summary>
            public int FilePercentage { get; set; }
            }
        #endregion

        #region Constructors
        /// <summary>
        /// Construct a Background worker for all this stuff.
        /// </summary>
        /// <param name="files">The files to move</param>
        /// <param name="moveDelegate">
        /// If supplied, is called to do the move. If not, File.Move will be used.
        /// Note that this delegate will be called on the background thread, so any
        /// control access in your method will need invoking:
        ///         private bool MoveIt(FileMove file)
        ///             {
        ///             if (InvokeRequired)
        ///                 {
        ///                 Invoke(new MethodInvoker(() => { MoveIt(file); }));
        ///                 // Do long operations here!
        ///                 Thread.Sleep(1000);
        ///                 return true;
        ///                 }
        ///             else
        ///                 {
        ///                 // Do control updates here!
        ///                 dgvResults.Rows.Add("Move: " + file);
        ///                 return true;
        ///                 }
        ///             }
        /// </param>
        /// <param name="updateDelegate">
        /// If supplied, is called to update any database
        /// Note that this delegate will be called on the background thread, so any
        /// control access in your method will need invoking:
        ///         private bool UpdateIt(FileMove file)
        ///             {
        ///             if (InvokeRequired)
        ///                 {
        ///                 Invoke(new MethodInvoker(() => { MoveIt(file); }));
        ///                 // Do long operations here!
        ///                 Thread.Sleep(1000);
        ///                 return true;
        ///                 }
        ///             else
        ///                 {
        ///                 // Do control updates here!
        ///                 dgvResults.Rows.Add("Move: " + file);
        ///                 return true;
        ///                 }
        ///             }
        /// </param>
        /// <param name="moveFileAction">Text to show in progress window instead of the default.</param>
        /// <param name="updateDBAction">Text to show in progress window instead of the default.</param>
        /// <param name="skippingAction">Text to show in progress window instead of the default.</param>
        /// <param name="closeOnDone">If true, the form will close when run completed</param>
        public frmMoveFilesInBackground(IEnumerable<FileMove> files,
                                        FileMove.MoveFile moveDelegate = null,
                                        FileMove.UpdateDB updateDelegate = null,
                                        string moveFileAction = null,
                                        string updateDBAction = null,
                                        string skippingAction = null,
                                        bool closeOnDone = false)
            {
            InitializeComponent();
            if (moveFileAction == null) moveFileAction = "Moving title...";
            if (updateDBAction == null) updateDBAction = "Updating database...";
            if (skippingAction == null) skippingAction = "Skipping title...";
            this.moveDelegate = moveDelegate;
            this.updateDelegate = updateDelegate;
            this.files = files;
            this.moveFileAction = moveFileAction;
            this.updateDBAction = updateDBAction;
            this.skippingAction = skippingAction;
            this.closeOnDone = closeOnDone;
            string initData = "";
            tbInfo.Text = initData;
            tbInfo.Visible = cancel;
            }
        #endregion

        #region Events
        #region Event Constructors
        /// <summary>
        /// Event to indicate all files moved
        /// </summary>
        public event EventHandler MoveCompleted;
        /// <summary>
        /// Called to signal to subscribers that all files moved
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnMoveCompleted(EventArgs e)
            {
            EventHandler eh = MoveCompleted;
            if (eh != null)
                {
                eh(this, e);
                }
            }
        #endregion

        #region Event Handlers
        #region Form
        /// <summary>
        /// Shown - start the move
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmMoveFilesInBackground_Shown(object sender, EventArgs e)
            {
            DoBackgroundMove();
            }
        /// <summary>
        /// Restore size and location (if the user doesn't
        /// override it)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmMoveFilesInBackground_Load(object sender, EventArgs e)
            {
            if ((ModifierKeys & Keys.Shift) == 0)
                {
                this.LoadLocation();
                }
            }
        /// <summary>
        /// Save the size and location (if the used doesn't
        /// override it)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmMoveFilesInBackground_FormClosing(object sender, FormClosingEventArgs e)
            {
            if ((ModifierKeys & Keys.Shift) == 0)
                {
                this.SaveLocation();
                }
            }
        #endregion

        #region Buttons
        /// <summary>
        /// Stop moving at end current operation.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void butStop_Click(object sender, EventArgs e)
            {
            cancel = true;
            }
        #endregion

        #region Worker
        /// <summary>
        /// Move the actual files.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tidyFiles_DoWork(object sender, DoWorkEventArgs e)
            {
            BackgroundWorker worker = sender as BackgroundWorker;
            if (worker != null)
                {
                int fileNumber = 1;
                worker.ReportProgress(0, new ProgressReport { Action = "Initializing", Filename = "", FileNumber = 0, FilesCount = 0 });

                foreach (FileMove file in files)
                    {
                    ProgressReport pr = new ProgressReport { FilesCount = files.Count() };
                    if (cancel)
                        {
                        pr.Action = "Cancelled by user";
                        pr.Filename = "";
                        worker.ReportProgress(pr.FilesCount, pr);
                        break;
                        }
                    string title = file.Title;
                    string fnOld = file.OldPath;
                    string fnNew = file.NewPath;
                    Guid id = file.FileID;
                    pr.FileNumber = fileNumber;
                    pr.Filename = Path.GetFileNameWithoutExtension(fnOld);
                    if (fnNew != fnOld)
                        {
                        try
                            {
                            pr.Action = moveFileAction;
                            worker.ReportProgress(fileNumber, pr);
                            if (moveDelegate != null)
                                {
                                if (!moveDelegate(file))
                                    {
                                    // Move failed - do not update.
                                    continue;
                                    }
                                }
                            else
                                {
                                if (File.Exists(fnOld))
                                    {
                                    string path = Path.GetDirectoryName(fnNew);
                                    if (!Directory.Exists(path))
                                        {
                                        Directory.CreateDirectory(path);
                                        }
                                    MoveFile(fnOld, fnNew, worker, pr);
                                    }
                                else if (!File.Exists(fnNew))
                                    {
                                    // File is completely missing - DB problem?
                                    throw new IOException("Neither the source nor the destination files could be found");
                                    }
                                }
                            if (updateDelegate != null)
                                {
                                pr.Action = updateDBAction;
                                worker.ReportProgress(fileNumber, pr);
                                if (!updateDelegate(file))
                                    {
                                    // Update failed - end run
                                    break;
                                    }
                                }
                            }
                        catch (Exception ex)
                            {
                            string problem = string.Format("Problem with:\n   \"{0}\"\n   \"{1}\"\n   \"{2}\"\n   {3}\n", title, fnOld, fnNew, ex);
                            worker.ReportProgress(fileNumber, new ProgressReport
                            {
                                Action = problem,
                                Filename = fnOld,
                                FileNumber = fileNumber,
                                FilesCount = files.Count()
                            });
                            }
                        }
                    else
                        {
                        // Skip file
                        pr.Action = skippingAction;
                        worker.ReportProgress(fileNumber, pr);
                        }
                    fileNumber++;
                    }
                }
            }
        /// <summary>
        /// Move operation progress report
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tidyFiles_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
            int progress = e.ProgressPercentage;
            ProgressReport report = e.UserState as ProgressReport;
            if (report == null)
                {
                tbInfo.Text = "Working...";
                pbShow.Visible = false;
                }
            else
                {
                tbInfo.Lines = string.Format("{0}\n{1}/{2}\n{3}", report.Action, report.FileNumber, report.FilesCount, report.Filename).Split('\n');
                pbShow.Maximum = report.FilesCount;
                pbShow.Visible = true;
                if (progress >= 0)
                    {
                    int newIndex = dgvHistory.Rows.Add(report.Action, report.Filename);
                    dgvHistory.CurrentCell = dgvHistory.Rows[newIndex].Cells[0];
                    Text = string.Format("Moving: {0}", report.Action);
                    TaskbarManager.Instance.SetProgressValue(report.FileNumber, report.FilesCount);
                    }
                else
                    {
                    progress = -progress;
                    }
                }
            tbInfo.Visible = true;
            if (report.FilePercentage > 0)
                {
                pbFileProgress.Visible = true;
                pbFileProgress.Value = report.FilePercentage;
                }
            else
                {
                pbFileProgress.Visible = false;
                }
            pbShow.Value = progress;
            }
        /// <summary>
        /// All done.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tidyFiles_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
            pbShow.Visible = false;
            pbFileProgress.Visible = false;
            butStop.Enabled = false;
            tbInfo.Text = "Completed";
            Text = "Move operation completed";
            TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.NoProgress);
            OnMoveCompleted(new EventArgs());
            if (closeOnDone)
                {
                Close();
                }
            }
        #endregion

        #endregion
        #endregion

        #region Public Methods
        /// <summary>
        /// Starts to cancel any existing operation.
        /// </summary>
        public void Cancel()
            {
            if (IsProcessing)
                {
                cancel = true;
                }
            }
        /// <summary>
        /// Do the move without displaying the form
        /// </summary>
        public void SteathMove()
            {
            DoBackgroundMove();
            }
        #endregion

        #region Public Static Methods
        #region Do Copy
                /// <summary>
        /// Create a list of files and move them in the background.
        /// </summary>
        /// <param name="sourceFolder">
        /// Source folder for files
        /// </param>
        /// <param name="destinationFolder">
        /// Destination folder for files
        /// </param>
        /// <param name="wantedExtensions">
        /// List of wanted extensions.
        /// If not provided, all files are wanted.
        /// </param>
        /// <param name="unwantedExtensions">
        /// List of unwanted extensions
        /// If not provided, no files are excluded.
        /// </param>
        /// <param name="moveDelegate">
        /// If supplied, is called to do the move. If not, File.Move will be used.
        /// Note that this delegate will be called on the background thread, so any
        /// control access in your method will need invoking:
        ///         private bool MoveIt(FileMove file)
        ///             {
        ///             if (InvokeRequired)
        ///                 {
        ///                 Invoke(new MethodInvoker(() => { MoveIt(file); }));
        ///                 // Do long operations here!
        ///                 Thread.Sleep(1000);
        ///                 return true;
        ///                 }
        ///             else
        ///                 {
        ///                 // Do control updates here!
        ///                 dgvResults.Rows.Add("Move: " + file);
        ///                 return true;
        ///                 }
        ///             }
        /// </param>
        /// <param name="updateDelegate">
        /// If supplied, is called to update any database
        /// Note that this delegate will be called on the background thread, so any
        /// control access in your method will need invoking:
        ///         private bool UpdateIt(FileMove file)
        ///             {
        ///             if (InvokeRequired)
        ///                 {
        ///                 Invoke(new MethodInvoker(() => { MoveIt(file); }));
        ///                 // Do long operations here!
        ///                 Thread.Sleep(1000);
        ///                 return true;
        ///                 }
        ///             else
        ///                 {
        ///                 // Do control updates here!
        ///                 dgvResults.Rows.Add("Move: " + file);
        ///                 return true;
        ///                 }
        ///             }
        /// </param>
        /// <param name="moveFileAction">Text to show in progress window instead of the default.</param>
        /// <param name="updateDBAction">Text to show in progress window instead of the default.</param>
        /// <param name="skippingAction">Text to show in progress window instead of the default.</param>
        /// <param name="closeOnDone">If true, the form will close when run completed</param>
        public static frmMoveFilesInBackground DoCopy(string sourceFolder,
                                  string destinationFolder,
                                  IEnumerable<string> wantedExtensions = null,
                                  IEnumerable<string> unwantedExtensions = null,
                                  FileMove.MoveFile moveDelegate = null,
                                  FileMove.UpdateDB updateDelegate = null,
                                  string moveFileAction = null,
                                  string updateDBAction = null,
                                  string skippingAction = null,
                                  bool closeOnDone = false)
            {
            if (unwantedExtensions == null) unwantedExtensions = new List<string>();
            List<FileMove> files = new List<FileMove>();
            Cursor.Current = Cursors.WaitCursor;
            string[] rawData = Directory.GetFiles(sourceFolder, "*.*", SearchOption.AllDirectories);

            files.AddRange(rawData.Where(r => (wantedExtensions == null ? true : wantedExtensions.Contains(Path.GetExtension(r))) &&
                                             !unwantedExtensions.Contains(Path.GetExtension(r)))
                                  .Select(w => new FileMove(Path.GetFileNameWithoutExtension(w), w, w.Replace(sourceFolder, destinationFolder))));
            Cursor.Current = Cursors.Default;
            return DoCopy(files, moveDelegate, updateDelegate, moveFileAction, updateDBAction, skippingAction, closeOnDone);
            }
        /// <summary>
        /// Create a list of files and move them in the background.
        /// </summary>
        /// <param name="files">
        /// List of files to move
        /// </param>
        /// <param name="moveDelegate">
        /// If supplied, is called to do the move. If not, File.Move will be used.
        /// Note that this delegate will be called on the background thread, so any
        /// control access in your method will need invoking:
        ///         private bool MoveIt(FileMove file)
        ///             {
        ///             if (InvokeRequired)
        ///                 {
        ///                 Invoke(new MethodInvoker(() => { MoveIt(file); }));
        ///                 // Do long operations here!
        ///                 Thread.Sleep(1000);
        ///                 return true;
        ///                 }
        ///             else
        ///                 {
        ///                 // Do control updates here!
        ///                 dgvResults.Rows.Add("Move: " + file);
        ///                 return true;
        ///                 }
        ///             }
        /// </param>
        /// <param name="updateDelegate">
        /// If supplied, is called to update any database
        /// Note that this delegate will be called on the background thread, so any
        /// control access in your method will need invoking:
        ///         private bool UpdateIt(FileMove file)
        ///             {
        ///             if (InvokeRequired)
        ///                 {
        ///                 Invoke(new MethodInvoker(() => { MoveIt(file); }));
        ///                 // Do long operations here!
        ///                 Thread.Sleep(1000);
        ///                 return true;
        ///                 }
        ///             else
        ///                 {
        ///                 // Do control updates here!
        ///                 dgvResults.Rows.Add("Move: " + file);
        ///                 return true;
        ///                 }
        ///             }
        /// </param>
        /// <param name="moveFileAction">Text to show in progress window instead of the default.</param>
        /// <param name="updateDBAction">Text to show in progress window instead of the default.</param>
        /// <param name="skippingAction">Text to show in progress window instead of the default.</param>
        /// <param name="closeOnDone">If true, the form will close when run completed</param>
        public static frmMoveFilesInBackground DoCopy(IEnumerable<FileMove> files,
                                  FileMove.MoveFile moveDelegate = null,
                                  FileMove.UpdateDB updateDelegate = null,
                                  string moveFileAction = null,
                                  string updateDBAction = null,
                                  string skippingAction = null,
                                  bool closeOnDone = false)
            {
            frmMoveFilesInBackground move = new frmMoveFilesInBackground(files, moveDelegate, updateDelegate, moveFileAction, updateDBAction, skippingAction, closeOnDone);
            move.doCopyOnly = true;
            move.Show();
            Cursor.Current = Cursors.Default;
            return move;
            }
        #endregion

        #region Do Move
        /// <summary>
        /// Create a list of files and move them in the background.
        /// </summary>
        /// <param name="sourceFolder">
        /// Source folder for files
        /// </param>
        /// <param name="destinationFolder">
        /// Destination folder for files
        /// </param>
        /// <param name="wantedExtensions">
        /// List of wanted extensions.
        /// If not provided, all files are wanted.
        /// </param>
        /// <param name="unwantedExtensions">
        /// List of unwanted extensions
        /// If not provided, no files are excluded.
        /// </param>
        /// <param name="moveDelegate">
        /// If supplied, is called to do the move. If not, File.Move will be used.
        /// Note that this delegate will be called on the background thread, so any
        /// control access in your method will need invoking:
        ///         private bool MoveIt(FileMove file)
        ///             {
        ///             if (InvokeRequired)
        ///                 {
        ///                 Invoke(new MethodInvoker(() => { MoveIt(file); }));
        ///                 // Do long operations here!
        ///                 Thread.Sleep(1000);
        ///                 return true;
        ///                 }
        ///             else
        ///                 {
        ///                 // Do control updates here!
        ///                 dgvResults.Rows.Add("Move: " + file);
        ///                 return true;
        ///                 }
        ///             }
        /// </param>
        /// <param name="updateDelegate">
        /// If supplied, is called to update any database
        /// Note that this delegate will be called on the background thread, so any
        /// control access in your method will need invoking:
        ///         private bool UpdateIt(FileMove file)
        ///             {
        ///             if (InvokeRequired)
        ///                 {
        ///                 Invoke(new MethodInvoker(() => { MoveIt(file); }));
        ///                 // Do long operations here!
        ///                 Thread.Sleep(1000);
        ///                 return true;
        ///                 }
        ///             else
        ///                 {
        ///                 // Do control updates here!
        ///                 dgvResults.Rows.Add("Move: " + file);
        ///                 return true;
        ///                 }
        ///             }
        /// </param>
        /// <param name="moveFileAction">Text to show in progress window instead of the default.</param>
        /// <param name="updateDBAction">Text to show in progress window instead of the default.</param>
        /// <param name="skippingAction">Text to show in progress window instead of the default.</param>
        /// <param name="closeOnDone">If true, the form will close when run completed</param>
        public static frmMoveFilesInBackground DoMove(string sourceFolder,
                                  string destinationFolder,
                                  IEnumerable<string> wantedExtensions = null,
                                  IEnumerable<string> unwantedExtensions = null,
                                  FileMove.MoveFile moveDelegate = null,
                                  FileMove.UpdateDB updateDelegate = null,
                                  string moveFileAction = null,
                                  string updateDBAction = null,
                                  string skippingAction = null,
                                  bool closeOnDone = false)
            {
            if (unwantedExtensions == null) unwantedExtensions = new List<string>();
            List<FileMove> files = new List<FileMove>();
            Cursor.Current = Cursors.WaitCursor;
            string[] rawData = Directory.GetFiles(sourceFolder, "*.*", SearchOption.AllDirectories);

            files.AddRange(rawData.Where(r => (wantedExtensions == null ? true : wantedExtensions.Contains(Path.GetExtension(r))) &&
                                             !unwantedExtensions.Contains(Path.GetExtension(r)))
                                  .Select(w => new FileMove(Path.GetFileNameWithoutExtension(w), w, w.Replace(sourceFolder, destinationFolder))));
            Cursor.Current = Cursors.Default;
            return DoMove(files, moveDelegate, updateDelegate, moveFileAction, updateDBAction, skippingAction, closeOnDone);
            }
        /// <summary>
        /// Create a list of files and move them in the background.
        /// </summary>
        /// <param name="files">
        /// List of files to move
        /// </param>
        /// <param name="moveDelegate">
        /// If supplied, is called to do the move. If not, File.Move will be used.
        /// Note that this delegate will be called on the background thread, so any
        /// control access in your method will need invoking:
        ///         private bool MoveIt(FileMove file)
        ///             {
        ///             if (InvokeRequired)
        ///                 {
        ///                 Invoke(new MethodInvoker(() => { MoveIt(file); }));
        ///                 // Do long operations here!
        ///                 Thread.Sleep(1000);
        ///                 return true;
        ///                 }
        ///             else
        ///                 {
        ///                 // Do control updates here!
        ///                 dgvResults.Rows.Add("Move: " + file);
        ///                 return true;
        ///                 }
        ///             }
        /// </param>
        /// <param name="updateDelegate">
        /// If supplied, is called to update any database
        /// Note that this delegate will be called on the background thread, so any
        /// control access in your method will need invoking:
        ///         private bool UpdateIt(FileMove file)
        ///             {
        ///             if (InvokeRequired)
        ///                 {
        ///                 Invoke(new MethodInvoker(() => { MoveIt(file); }));
        ///                 // Do long operations here!
        ///                 Thread.Sleep(1000);
        ///                 return true;
        ///                 }
        ///             else
        ///                 {
        ///                 // Do control updates here!
        ///                 dgvResults.Rows.Add("Move: " + file);
        ///                 return true;
        ///                 }
        ///             }
        /// </param>
        /// <param name="moveFileAction">Text to show in progress window instead of the default.</param>
        /// <param name="updateDBAction">Text to show in progress window instead of the default.</param>
        /// <param name="skippingAction">Text to show in progress window instead of the default.</param>
        /// <param name="closeOnDone">If true, the form will close when run completed</param>
        public static frmMoveFilesInBackground DoMove(IEnumerable<FileMove> files,
                                  FileMove.MoveFile moveDelegate = null,
                                  FileMove.UpdateDB updateDelegate = null,
                                  string moveFileAction = null,
                                  string updateDBAction = null,
                                  string skippingAction = null,
                                  bool closeOnDone = false)
            {
            frmMoveFilesInBackground move = new frmMoveFilesInBackground(files, moveDelegate, updateDelegate, moveFileAction, updateDBAction, skippingAction, closeOnDone);
            move.Show();
            Cursor.Current = Cursors.Default;
            return move;
            }
        
        #endregion        

        /// <summary>
        /// Returns the revision history for this module.
        /// </summary>
        /// <returns></returns>
        public static string GetRevisionHistory()
            {
            Assembly assembly = Assembly.GetExecutingAssembly();
            Stream stream = assembly.GetManifestResourceStream("BackgroundFileMove.Resources.Documents.RevisionHistory.txt");
            StreamReader reader = new StreamReader(stream);
            return reader.ReadToEnd();
            }
        /// <summary>
        /// Returns true if the drive is available.
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static bool IsDriveAvailable(string path)
            {
            DriveInfo[] drives = DriveInfo.GetDrives();
            DriveInfo drive = drives.FirstOrDefault(d => path.StartsWith(d.Name));
            return drive != null && drive.IsReady;
            }
        #endregion

        #region Overrides
        #endregion

        #region Private Methods
        /// <summary>
        /// Do the actual operation start
        /// </summary>
        private void DoBackgroundMove()
            {
            if (!cancel)
                {
                TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Normal);
                BackgroundWorker tidyFiles = new BackgroundWorker();
                tidyFiles.WorkerReportsProgress = true;
                tidyFiles.DoWork += new DoWorkEventHandler(tidyFiles_DoWork);
                tidyFiles.ProgressChanged += new ProgressChangedEventHandler(tidyFiles_ProgressChanged);
                tidyFiles.RunWorkerCompleted += new RunWorkerCompletedEventHandler(tidyFiles_RunWorkerCompleted);
                tidyFiles.RunWorkerAsync();
                butStop.Enabled = true;
                }
            }
        /// <summary>
        /// Do the actual file move.
        /// </summary>
        /// <param name="src"></param>
        /// <param name="dst"></param>
        /// <param name="worker"></param>
        /// <param name="prMain"></param>
        private void MoveFile(string src, string dst, BackgroundWorker worker = null, ProgressReport prMain = null)
            {
            if (src != dst)
                {
                // Copy the file itself.
                int iSrc = src.IndexOf(':');
                int iDst = dst.IndexOf(':');
                FileInfo fiSrc = new FileInfo(src);
                if (fiSrc.Length < blockSize || (iSrc > 0 && iDst > 0 && iSrc == iDst && src.Substring(0, iSrc) == dst.Substring(0, iDst)))
                    {
                    // On same drive or trivial size - move it via the file system
                    if (doCopyOnly)
                        {
                        File.Copy(src, dst);
                        }
                    else
                        {
                        File.Move(src, dst);
                        }
                    }
                else
                    {
                    // Needs to be moved "properly".
                    using (Stream sr = new FileStream(src, FileMode.Open))
                        {
                        using (Stream sw = new FileStream(dst, FileMode.Create))
                            {
                            long total = sr.Length;
                            long bytes = 0;
                            long cnt = total;
                            int progress = 0;
                            while (cnt > 0)
                                {
                                int n = sr.Read(transfer, 0, blockSize);
                                sw.Write(transfer, 0, n);
                                bytes += n;
                                cnt -= n;
                                int percent = (int)((bytes * 100) / total);
                                if (progress != percent)
                                    {
                                    // Report progress
                                    progress = percent;
                                    if (worker != null && prMain != null)
                                        {
                                        ProgressReport pr = new ProgressReport
                                        {
                                            FilesCount = prMain.FilesCount,
                                            FileNumber = prMain.FileNumber,
                                            Filename = prMain.Filename,
                                            Action = prMain.Action,
                                            FilePercentage = percent
                                        };
                                        worker.ReportProgress(-prMain.FileNumber, pr);
                                        }
                                    }
                                }
                            }
                        }
                    // Update the fileinfo.
                    FileInfo fiDst = new FileInfo(dst);
                    fiDst.Attributes = fiSrc.Attributes;
                    fiDst.CreationTime = fiSrc.CreationTime;
                    fiDst.CreationTimeUtc = fiSrc.CreationTimeUtc;
                    fiDst.IsReadOnly = fiSrc.IsReadOnly;
                    fiDst.LastAccessTime = fiSrc.LastAccessTime;
                    fiDst.LastAccessTimeUtc = fiSrc.LastAccessTimeUtc;
                    fiDst.LastWriteTime = fiSrc.LastWriteTime;
                    fiDst.LastWriteTimeUtc = fiSrc.LastWriteTimeUtc;
                    // And remove the source
                    if (!doCopyOnly)
                        {
                        File.Delete(src);
                        }
                    }
                }
            }
        #endregion
        }
    }
Look at the DoBackgroundMovemethod - it builds the worker as needed and kicks it off to throw files around (normally between my HDD and NAS, which is a relatively slow operation)
To use it, I construct the form instance, pass it the files list and show it - it then updates my as it moves the files.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!

GeneralRe: BackGroundWorker gives runtime error Pin
Alex Dunlop12-Feb-21 1:44
Alex Dunlop12-Feb-21 1:44 
GeneralRe: BackGroundWorker gives runtime error Pin
OriginalGriff12-Feb-21 2:11
mveOriginalGriff12-Feb-21 2:11 
GeneralRe: BackGroundWorker gives runtime error Pin
Alex Dunlop12-Feb-21 6:03
Alex Dunlop12-Feb-21 6:03 
AnswerRe: BackGroundWorker gives runtime error Pin
Ralf Meier10-Feb-21 4:48
mveRalf Meier10-Feb-21 4:48 
GeneralRe: BackGroundWorker gives runtime error Pin
Alex Dunlop10-Feb-21 4:57
Alex Dunlop10-Feb-21 4:57 
GeneralRe: BackGroundWorker gives runtime error Pin
Alex Dunlop10-Feb-21 7:47
Alex Dunlop10-Feb-21 7:47 
GeneralRe: BackGroundWorker gives runtime error Pin
Luc Pattyn10-Feb-21 9:26
sitebuilderLuc Pattyn10-Feb-21 9:26 
GeneralRe: BackGroundWorker gives runtime error Pin
Alex Dunlop10-Feb-21 16:49
Alex Dunlop10-Feb-21 16:49 
GeneralRe: BackGroundWorker gives runtime error Pin
Luc Pattyn10-Feb-21 17:22
sitebuilderLuc Pattyn10-Feb-21 17:22 
GeneralRe: BackGroundWorker gives runtime error Pin
Alex Dunlop13-Feb-21 8:24
Alex Dunlop13-Feb-21 8:24 
GeneralRe: BackGroundWorker gives runtime error Pin
Luc Pattyn13-Feb-21 8:28
sitebuilderLuc Pattyn13-Feb-21 8:28 
AnswerRe: BackGroundWorker gives runtime error Pin
Ralf Meier10-Feb-21 20:22
mveRalf Meier10-Feb-21 20:22 
AnswerRe: BackGroundWorker gives runtime error Pin
Eddy Vluggen11-Feb-21 14:21
professionalEddy Vluggen11-Feb-21 14:21 
QuestionMonitor data using C# and ESP8266 Pin
pinout_19-Feb-21 1:56
pinout_19-Feb-21 1:56 
AnswerRe: Monitor data using C# and ESP8266 Pin
OriginalGriff9-Feb-21 2:20
mveOriginalGriff9-Feb-21 2:20 
GeneralRe: Monitor data using C# and ESP8266 Pin
pinout_19-Feb-21 2:31
pinout_19-Feb-21 2:31 
AnswerRe: Monitor data using C# and ESP8266 Pin
Gerry Schmitz9-Feb-21 7:54
mveGerry Schmitz9-Feb-21 7:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.