Bluevels
Bluevels

Reputation: 29

How do i fix backgroundworker is busy c# code

i keep getting background worker is busy when i run my code. any help?

       struct FtpSetting
    {
        public string Server { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public string FileName { get; set; }
        public string FullName { get; set; }
    }

    FtpSetting _inputParameter;

    private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        string fileName = ((FtpSetting)e.Argument).FileName;
        string fullName = ((FtpSetting)e.Argument).FullName;
        string userName = ((FtpSetting)e.Argument).Username;
        string password = ((FtpSetting)e.Argument).Password;
        string server = ((FtpSetting)e.Argument).Server;
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(string.Format("{0}/{1}", server, fileName)));
        request.Method = WebRequestMethods.Ftp.UploadFile;
        request.Credentials = new NetworkCredential(userName, password);
        Stream ftpStream = request.GetRequestStream();
        FileStream fs = File.OpenRead(fullName);
        byte[] buffer = new byte[1024];
        double total = (double)fs.Length;
        int byteRead = 0;
        double read = 0;
        do
        {
            if (!backgroundWorker.CancellationPending)
            {
                //Upload file & update process bar
                byteRead = fs.Read(buffer, 0, 1024);
                ftpStream.Write(buffer, 0, byteRead);
                read += (double)byteRead;
                double percentage = read / total * 100;
                backgroundWorker.ReportProgress((int)percentage);
            }
        }
        while (byteRead != 0);
        fs.Close();
        ftpStream.Close();
    }

    private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        lblStatus.Text = $"Uploaded {e.ProgressPercentage} %";
        progressBar.Value = e.ProgressPercentage;
        progressBar.Update();
    }

    private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        lblStatus.Text = "Upload complete !";
    }

    private void btnUpload_Click(object sender, EventArgs e)
    {
        string dir = "C:\\Users\\bluevels\\Pictures\\";
        string[] files = Directory.GetFiles(dir);
        foreach (string file in files)
        {

            string FileName = Path.GetFileName(file);

            FileInfo fi = new FileInfo(FileName);
            _inputParameter.Username = txtUserName.Text;
            _inputParameter.Password = txtPassword.Text;
            _inputParameter.Server = txtServer.Text;
            _inputParameter.FileName = fi.Name;
            _inputParameter.FullName = fi.FullName;
            backgroundWorker.RunWorkerAsync(_inputParameter);

        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

i keep getting the error from this line

backgroundWorker.RunWorkerAsync(_inputParameter);

Upvotes: 0

Views: 152

Answers (2)

Bluevels
Bluevels

Reputation: 29

so i figured it our. all i had to do was put the loop in the backgroundworker as seen in the code below.

    struct FtpSetting
    {
        public string Server { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }

    }

    FtpSetting _inputParameter;

    private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        string fileName = "";
        string fullName = "";

        string dir = "C:\\Users\\bluevels\\Desktop\\ww\\";
        string[] files = Directory.GetFiles(dir);
        foreach (string file in files)
        {

            string FileName = "C:\\Users\\bluevels\\Desktop\\ww\\" + Path.GetFileName(file);


            FileInfo fi = new FileInfo(FileName);

            fileName = fi.Name;
            fullName = fi.FullName;





            string userName = ((FtpSetting)e.Argument).Username;
            string password = ((FtpSetting)e.Argument).Password;
            string server = ((FtpSetting)e.Argument).Server;
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(string.Format("{0}/{1}", server, fileName)));
            request.Method = WebRequestMethods.Ftp.UploadFile;
            request.Credentials = new NetworkCredential(userName, password);
            Stream ftpStream = request.GetRequestStream();
            FileStream fs = File.OpenRead(fullName);
            byte[] buffer = new byte[1024];
            double total = (double)fs.Length;
            int byteRead = 0;
            double read = 0;
            do
            {
                if (!backgroundWorker.CancellationPending)
                {
                    //Upload file & update process bar
                    byteRead = fs.Read(buffer, 0, 1024);
                    ftpStream.Write(buffer, 0, byteRead);
                    read += (double)byteRead;
                    double percentage = read / total * 100;
                    backgroundWorker.ReportProgress((int)percentage);
                }
            }
            while (byteRead != 0);
            fs.Close();
            ftpStream.Close();
        }
    }

    private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        lblStatus.Text = $"Uploaded {e.ProgressPercentage} %";
        progressBar.Value = e.ProgressPercentage;
        progressBar.Update();
    }

    private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        lblStatus.Text = "Upload complete !";
    }

    private void btnUpload_Click(object sender, EventArgs e)
    {
                _inputParameter.Username = txtUserName.Text;
                _inputParameter.Password = txtPassword.Text;
                _inputParameter.Server = txtServer.Text;
                backgroundWorker.RunWorkerAsync(_inputParameter);


    }

the percentage calculation also works fine with every file.

Upvotes: 0

user585968
user585968

Reputation:

By placing RunWorkerAsync() inside the foreach, you are attempting to start multiple copies of the worker using the same instance whilst it is already running.

Consider moving the loop into the worker itself:

class FtpSetting
{
    public string Server { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
    public string[] Files { get; set; }
}

private void btnUpload_Click(object sender, EventArgs e)
{
    if (backgroundWorker.IsBusy)
       return;

      string dir = "C:\\Users\\bluevels\\Pictures\\";
      string[] files = Directory.GetFiles(dir);

     _inputParameter.Username = txtUserName.Text;
     _inputParameter.Password = txtPassword.Text;
     _inputParameter.Server = txtServer.Text;
     _inputParameter.Files = files;
     backgroundWorker.RunWorkerAsync(_inputParameter);
}

Naturally the body of the worker will need to be changed as e is a list of files now. The rest of the properties can be read directly from instance fields.

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    var setting = (FtpSetting)e.Argument;
    ...
    for (int fileNum = 0; fileNum < setting.Files.Length; fileNum++)
    {
         if (backgroundWorker.CancellationPending)
             break;

         do
             ...
             // use setings.Files[fileNum]
             // also divide percentage done by setting.Files.Length e.g.
             double percentage = (100/setting.Files.Length)+fileNum + (read / total * 100);
             ...
    }

  }

That way if you ever decide to do true concurrent downloading from multiple sites (you'll need multiple workers or perhaps consider TPL DataFlow) there will be minimal code changes.

Upvotes: 3

Related Questions