Without a good, minimal, complete code example that reliably reproduces the problem and shows your precise scenario, it is impossible to know for sure what the best answer would be. That said, if I understand correctly you have: a progress bar; and a button; and some process that, when it is nearly done, you want for the button to be shown, and of course for the progress to be updated continuously.
There are a number of good answers on Stack Overflow already discussing the correct use of background tasks, asynchronous methods, and progress bars, so I won't belabor those points too much. But I will show quickly how your code might be restructured to accomplish what you want.
Let's assume this all starts with the click of some button (maybe even the one you are setting to be invisible). Then we might refactor your code above, which presumably appears in the event handler for that button click, to look something like this:
private async void button1_Click(object sender, EventArgs e) { button1.Visible = false; progressBar1.Minimum = 0; progressBar1.Maximum = 231; // Set up a callback that can be used to report progress on the UI thread Progress<int> progress = new Progress<int>(i => { progressBar1.Value = i; if (progressBar1.Value == 220) { button1.Visible = true; } }); // Perform your task; this will run in a different thread from the current, // UI thread, allowing the UI thread to do useful things like hiding the button // and updating the progress bar. Use of "await" here is what allows this // method to return, _temporarily_, so that the UI thread can continue to work await Task.Run(() => { for (i = 0; i <= 220; i++) { // do NOT do this in real code...this is just here to represent _some_ kind // of time-consuming operation that justifies the use of the progress bar //in the first place Thread.Sleep(250); // Now report the progress value; the "progress" object will handle // marshaling back to the UI thread to call the anonymous method // declared above during the initialization of "progress" progress.Report(i); } }); // Do any post-processing cleanup, UI updating, etc. here. This code // will execute only after the task started above has completed. }
EDIT:
Per the new requirements from the OP, here is a version of the above that makes the button visible only after all of the processing is done:
private async void button1_Click(object sender, EventArgs e) { button1.Visible = false; progressBar1.Minimum = 0; progressBar1.Maximum = 231; // Set up a callback that can be used to report progress on the UI thread Progress<int> progress = new Progress<int>(i => { progressBar1.Value = i; }); // Perform your task; this will run in a different thread from the current, // UI thread, allowing the UI thread to do useful things like hiding the button // and updating the progress bar. Use of "await" here is what allows this // method to return, _temporarily_, so that the UI thread can continue to work await Task.Run(() => { for (i = 0; i <= 220; i++) { // do NOT do this in real code...this is just here to represent _some_ kind // of time-consuming operation that justifies the use of the progress bar //in the first place Thread.Sleep(250); // Now report the progress value; the "progress" object will handle // marshaling back to the UI thread to call the anonymous method // declared above during the initialization of "progress" progress.Report(i); } }); // Do any post-processing cleanup, UI updating, etc. here. This code // will execute only after the task started above has completed. button1.Visible = true; }
Thread.Sleepin there to have it go slower.