我有下一个代码,并且工作正常:
private void BtBasicIntroClick(object sender, EventArgs e)
{
var stopwatch = new Stopwatch();
stopwatch.Reset();
stopwatch.Start();
var executionDataflowBlockOptions = new ExecutionDataflowBlockOptions
{
//TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(),
MaxDegreeOfParallelism = 1
};
var actionBlock = new ActionBlock<int>(s =>
{
//comboBox1.Items.Add((s*3).ToString());
Invoke(new Action(() => comboBox1.Items.Add((s * 3).ToString())));
}, executionDataflowBlockOptions);
var numeros = Enumerable.Range(0, 40000);
foreach (var numero in numeros)
{
actionBlock.Post(numero);
}
Task.Factory.StartNew(() =>
{
actionBlock.Completion.ContinueWith(delegate
{
stopwatch.Stop();
if (InvokeRequired)
{
Invoke(new Action(() =>
label1.Text = stopwatch.ElapsedMilliseconds.ToString(CultureInfo.InvariantCulture)));
}
});
actionBlock.Complete();
actionBlock.Completion.Wait();
});
}
Windows窗体工作正常......进程不会阻止UI
但是如果我将MaxDgreeOfParallelism更改为其他值(2或3或4 ...),UI将被阻止,直到进程完成。
我在Visual Studio中看到了Parallel Tasks窗口和Thread Window,在这两种情况下,一切都在Worked Threads中工作,但在后一种情况下(当MaxDgreeOfParallelism与1不同时)UI不会响应,直到进程完成
为什么?
答案 0 :(得分:1)
当我尝试使用您的代码时,即使使用MaxDegreeOfParallelism = 1
,也会一直阻止用户界面。那是因为你的所有块都是调用Invoke()
来阻止UI线程。
在某些情况下,一个线程一次又一次地调用Invoke()
的线程可能不足以完全阻止UI线程,但几乎肯定会有2个线程。
所以,你要做的事情没有任何意义。你不会从使用数据流或任何类似的东西中获得任何收益。
要解决此问题,应该在UI中拥有数千个项目。无论如何,没有人会去这么大的名单。