【发布时间】:2015-09-10 14:07:57
【问题描述】:
我一直在使用 C# 中的 async 和 await 制作进度条。我用以下代码制作了一个简单的表单Form1.cs:
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; }
}
在我的Program.cs,我有两种情况:
// 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();
为什么案例 1 会导致跨线程问题,但案例 2 可以正常工作?如果您想在表单本身之外使用 Report 方法,我觉得案例 1 可能是一个非常有用的构造。
编辑:我知道我可以使用 BeginInvoke 或类似的,但我的印象是 Async+Await 应该可以做到,所以我不再需要这样做了。
【问题讨论】:
-
stackoverflow.com/questions/17972268/… 中提供的大部分解释和工作示例(几乎重复)。 Servy 回答的确切问题(创建 Progress before 同步上下文创建)(也有许多类似的问题,还没有好的重复目标)。
标签: c# async-await