2

i am using async await task to run this code and i want to change the progress bar when extracting

public async Task<string> DownloadAndExtractFile(string source, string destination, string ItemDownload) //source = File Location //destination = Restore Location
    {
        string zPath = @"C:\Program Files\7-Zip\7zG.exe";
        ProcessStartInfo pro = new ProcessStartInfo();
        pro.WindowStyle = ProcessWindowStyle.Hidden;
        pro.FileName = zPath;
        pro.Arguments = "x \"" + source + "\" -o" + destination;

        await Task.Run(() =>
        {
            Restore.frmRestore.progressBar1.Value = 50; //already set to public
            try
            {
                Process x = Process.Start(pro);
                Task.WaitAll();
                Restore.frmRestore.progressBar1.Value = 100;//already set to public
                x.Close();
                Console.WriteLine("Extract Successful.");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

        }
           );

        return "Success";
    }

how to change the progressbar value when task running. this is the error "Cross-thread operation not valid: Control 'progressBar1' accessed from a thread other than the thread it was created on."

3 Answers 3

5

Use the Progress<T> type to report progress, as I describe on my blog:

public async Task<string> DownloadAndExtractFile(string source, string destination, string ItemDownload)
{
  string zPath = @"C:\Program Files\7-Zip\7zG.exe";
  ProcessStartInfo pro = new ProcessStartInfo();
  pro.WindowStyle = ProcessWindowStyle.Hidden;
  pro.FileName = zPath;
  pro.Arguments = "x \"" + source + "\" -o" + destination;

  IProgress<int> progress = new Progress<int>(
      value => { Restore.frmRestore.progressBar1.Value = value; });

  await Task.Run(() =>
  {
    progress.Report(50);
    try
    {
      Process x = Process.Start(pro);
      Task.WaitAll();
      progress.Report(100);
      x.Close();
      Console.WriteLine("Extract Successful.");
    }
    catch (Exception ex)
    {
      Console.WriteLine(ex.ToString());
    }
  });
  return "Success";
}
Sign up to request clarification or add additional context in comments.

2 Comments

I have used Signal R to update progress bar value in html element using asp .net MVC application , but Can I use the same in MVC web application ?
@stom: If you mean ASP.NET Core, then the built-in support for IProgress has been removed from SignalR. You can build it yourself, though.
0

You can use a Progress<T>. That allows you to inform the UI thread of your progress and update your progress bar.

So, at the place where call that task, do this:

Progress<int> progress = new Progress<int>(i => Restore.frmRestore.progressBar1.Value = i);
await DownloadAndExtractFile(source, destination, ItemDownload, progress);

And in your method you can use this progress like this:

public async Task<string> DownloadAndExtractFile(string source, string destination, string ItemDownload, IProgress<int> progress)
{
    // shortened for clarity
    await Task.Run(() =>
    {
        progress.Report(50);
        try
        {
            Process x = Process.Start(pro);
            Task.WaitAll();
            progress.Report(100);
            x.Close();
            Console.WriteLine("Extract Successful.");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    });

    return "Success";
}

Note: that you have to pass progress as interface type IProgress<int> to be able to access the Report method of that interface.

Comments

0

Direct solution, but not as fancy as Progress<T>:

Create a function:

private void UpdateProgress(int percent)
{
  if (Restore.frmRestore.progressBar1.InvokeRequired)
  {
    UpdateProgress.Invoke(percent);
  }
  else
  {
    Restore.frmRestore.progressBar1.Value = percent;
  }
}

And then call it instead of setting the value directly.

To clarify: .Invoke does execute the function on the main thread (which is the UI-Thread.).

This does 1:1 what you wan't but I would use Progress<T>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.