17792

How to change progressbar value when async task running

Question:

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."

Answer1:

<a href="http://blog.stephencleary.com/2013/09/taskrun-vs-backgroundworker-round-5.html" rel="nofollow">Use the Progress<T> type to report progress</a>, 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"; }

Answer2:

You can use a <a href="https://msdn.microsoft.com/en-us/library/hh193692%28v=vs.110%29.aspx" rel="nofollow">Progress<T></a>. 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"; }

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

Answer3:

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>

Recommend

  • Passing Data Between Threads
  • How do I limit my Windows application to spawning a single instance of a process?
  • How to make a progressbar run in a different thread in C#
  • Executing Command line .exe with parameters in C#
  • C#, Updating a Progress Bar Using Background Worker From a Different Class
  • Cannot terminate threads
  • How to alias an executable using Powershell permanently?
  • Find the associated program to open a file using Java
  • Upgrade to g++ 4.7 (with c++11 support): any ABI incompatibility?
  • subprocess.Popen('start') fails
  • Can I monitor the progress of an S3 download using the AWS SDK?
  • C# COM Component Fails To Read Config When Loaded Into An Unmanaged C++ App
  • How do I compile a C/C++ program through windows command prompt?
  • Visual studio alerts workspace already exists
  • Find VMID for running instance
  • How dotnet build chooses the output name
  • include dlls in visual studio c++ 2008
  • NSIS decompiler
  • netsh acl setting (need alternative method - registry settings?)
  • hide missing dates from x-axis ggplot2
  • aapt.exe'' finished with non-zero exit value 1
  • Compiling dlib on OS X
  • how to upload multiple files in c# windows application
  • Tamper-proof configuration files in .NET?
  • Code in Job's Script Block after Start-Process Does not Execute
  • How to install a .deb file on a jailbroken iphone programmatically?
  • Handling un-mapped Rest path
  • Illegal mix of collations for operation for date/time comparison
  • Sending data from AppleScript to FileMaker records
  • MySQL WHERE-condition in procedure ignored
  • Running a C# exe file
  • Adding custom controls to a full screen movie
  • SVN: Merging two branches together
  • Hibernate gives error error as “Access to DialectResolutionInfo cannot be null when 'hibernate.
  • How to set the response of a form post action to a iframe source?
  • How to CLICK on IE download dialog box i.e.(Open, Save, Save As…)
  • Change div Background jquery
  • Can Visual Studio XAML designer handle font family names with spaces as a resource?
  • Qt: Run a script BEFORE make
  • reshape alternating columns in less time and using less memory