我有一个包含Run()方法的类,该方法执行阻止UI的繁重操作。 我已经创建了该类的几个实例,我需要同步执行Run(),而无需阻止UI。 我已经设法使用BackgroundWorker但我不喜欢这个解决方案,因为“Application.DoEvents()”并且因为如果我需要等待后台工作者完成,那么没有使用BW。我应该使用同步操作。 任何想法我可以使用什么呢?
class MyClass
{
public void Run()
{
for (int i = 0; i < 1000; i++)
{
Console.WriteLine(i);
}
}
}
public partial class Form1 : Form
{
List<MyClass> lmc = new List<MyClass>();
public Form1()
{
InitializeComponent();
MyClass m1 = new MyClass();
MyClass m2 = new MyClass();
lmc.Add(m1);
lmc.Add(m2);
}
private void button1_Click(object sender, EventArgs e)
{
foreach (MyClass item in lmc)
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += bw_DoWork;
bw.WorkerSupportsCancellation = true;
bw.RunWorkerAsync(item);
while (bw.IsBusy)
{
Application.DoEvents();
}
}
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
((MyClass)e.Argument).Run();
((BackgroundWorker)sender).CancelAsync();
}
}
答案 0 :(得分:1)
“DoEvents”确实不是一个好方法。 我建议使用TPL任务。
private void button1_Click(object sender, EventArgs e)
{
Task t = new Task(() =>
{
lmc.ForEach(l => l.Run());
});
t.Start();
t.ContinueWith(_ =>
{
Invoke(new System.Action(UploadDone));
});
}
private void UploadDone()
{
Console.Write("Done");
}
发布UI的唯一方法是发布主线程。你必须开始一个新的线程。
BTW,如果lmc任务没有相互转发,你也可以Parallel Foreach
谢谢,
阿米尔