MaxDegreeOfParallelism блокирует основной поток?

У меня есть следующий код, и он отлично работает:

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 Forms работает нормально... процесс не блокирует пользовательский интерфейс

Но если я изменю MaxDgreeOfParallelism на другое значение (2, 3 или 4...), пользовательский интерфейс будет заблокирован до завершения процесса.

Я вижу окно параллельных задач и окно потока в Visual Studio, и в обоих случаях все работает в рабочих потоках, но в последнем случае (когда MaxDgreeOfParallelism отличается от 1) пользовательский интерфейс не отвечает, пока процесс не завершится

Почему?


person nicolocodev    schedule 19.10.2013    source источник
comment
Control.Invoke всегда запускается в потоке пользовательского интерфейса, и это единственная причина, по которой ваш код вообще запускается. Только поток пользовательского интерфейса может касаться элементов управления, и это невозможно обойти. Какую реальную проблему вы пытаетесь решить? Возможно, есть другие решения для этого   -  person Panagiotis Kanavos    schedule 08.11.2013


Ответы (1)


Когда я пробую ваш код, пользовательский интерфейс все время блокируется, даже с MaxDegreeOfParallelism = 1. Это потому, что все, что делает ваш блок, это вызывает Invoke(), который блокирует поток пользовательского интерфейса.

Вполне возможно, что при некоторых обстоятельствах одного потока, вызывающего Invoke() снова и снова, будет недостаточно, чтобы полностью заблокировать поток пользовательского интерфейса, но 2 потока почти наверняка будут.

Итак, то, что вы пытаетесь сделать, не имеет никакого смысла. Вы ничего не получите от использования потока данных или чего-то подобного.

Что вы должны сделать, чтобы исправить это, так это не иметь тысячи элементов в пользовательском интерфейсе. В любом случае ни один человек не пойдет по такому огромному списку.

person svick    schedule 19.10.2013