我开始尝试为Windows表单添加进度条,以更新在Parallel.Foreach循环中运行的代码的进度。 为此,UI线程必须可用于更新进度条。 我使用了一个Task来运行Parallel.Foreach循环,以允许UI线程更新进度条。
在Parallel.Foreach循环中执行的工作相当密集。 在使用Task运行程序的可执行文件后(而非在Visual Studio中进行调试),程序变得无响应。 如果我不使用Task运行程序,则情况并非如此。 我注意到两种情况之间的关键区别是:在没有Task的情况下运行程序时,程序占用大约80%的CPU,而在有Task的情况下只占用大约5%。
在Parallel.Foreach循环中执行的工作相当密集。 在使用Task运行程序的可执行文件后(而非在Visual Studio中进行调试),程序变得无响应。 如果我不使用Task运行程序,则情况并非如此。 我注意到两种情况之间的关键区别是:在没有Task的情况下运行程序时,程序占用大约80%的CPU,而在有Task的情况下只占用大约5%。
private void btnGenerate_Click(object sender, EventArgs e)
{
var list = GenerateList();
int value = 0;
var progressLock = new object ();
progressBar1.Maximum = list.Count();
Task t = new Task(() => Parallel.ForEach (list, item =>
{
DoWork ();
lock (progressLock)
{
value += 1;
}
}));
t.Start();
while (!t.IsCompleted)
{
progressBar1.Value = value;
Thread.Sleep (100);
}
}
附注:我知道
这里是关于IT技术的内容。 Interlocked.Increment(ref int___);
锁的替代品是有效的吗?这与IT技术有关。
我的问题有三个方面:
1.) 当负载较小时,为什么带有任务的程序会变得无响应?
2.) 使用Task来运行Parallel.Foreach是否会将Parallel.Foreach的线程池限制在仅运行任务的线程上?
3.) 是否有一种方法可以使UI线程响应而不需要使用取消标记并在0.1秒的持续时间内休眠?
非常感谢您的任何帮助或想法,我已经花费了很多时间研究此问题。如果我违反了任何发布格式或规则,我也向大家道歉。我尽力遵守规定,但可能会漏掉某些内容。
BackgroundWorker
或async
。 - SimpleVarDoWork()
访问了任何UI元素,将会导致死锁发生。 - Johnathon Sullinger