I've been working on a progress bar with async and await in C#. I made a simple form Form1.cs with the following code:
public partial class Form1 : Form
{
private Progress<TaskAsyncExProgress> progress;
public Form1(Progress<TaskAsyncExProgress> progress = null)
{
InitializeComponent();
if (progress == null)
{
this.progress = new Progress<TaskAsyncExProgress>();
}
else
{
this.progress = progress;
}
this.progress.ProgressChanged += (s, e) =>
{
Debug.WriteLine("Progress: " + e.ProgressPercentage + "%");
progressBar.Value += e.ProgressPercentage;
txtResult.Text += e.Text;
};
Shown += async (s, e) =>
{
try
{
await Task.Run(() => HardTask(progress));
txtResult.Text += "Done!";
}
finally
{
MessageBox.Show("Done!");
Close();
}
};
}
void HardTask(Progress<TaskAsyncExProgress> progress)
{
incrementProgress();
Thread.Sleep(5000);
}
public void incrementProgress()
{
Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
var args = new TaskAsyncExProgress();
args.ProgressPercentage = 1;
args.Text = i.ToString() + " ";
((IProgress<TaskAsyncExProgress>)progress).Report(args);
Thread.Sleep(10);
}
}
);
}
}
public class TaskAsyncExProgress
{
public int ProgressPercentage { get; set; }
public string Text { get; set; }
}
In my Program.cs, I have two cases:
// Case 1: This causes a cross-thread issue
//Progress<TaskAsyncExProgress> progress = new Progress<TaskAsyncExProgress>();
//Form1 frm = new Form1(progress);
// Case 2: This works fine
Form1 frm = new Form1();
frm.ShowDialog();
Why is it that Case 1 causes a cross-threading issue, but Case 2 works fine? I feel like Case 1 could be a pretty useful construct if you want to use the Report method outside of the form itself.
Edit: I know that I can use a BeginInvoke or similar, but I was under the impression that Async+Await were supposed to make it so that I don't need to do that anymore.