Как запустить два цикла foreach, которые диспетчер вызывает одновременно c# wpf - PullRequest
0 голосов
/ 17 февраля 2020

Можно ли отображать строки char по char в двух метках одновременно, используя два разных Dispatcher.BeginInvoke (new Action (()?

) У меня есть два цикла foreach, таких как:

        string str1 = "NUMBER OF PASSED:" + "\t\t" + passed1.ToString() + Environment.NewLine + "NUMBER OF FAILED:" + "\t" + failed1.ToString();

        foreach (var ch1 in str1)
        {
            var char_by_char1 = ch1;
            Dispatcher.BeginInvoke(new Action(() =>
            {                    
                first_result.Content += char_by_char1.ToString();
                System.Threading.Thread.Sleep(5);
            }), DispatcherPriority.Background);
        }


        string str2 = "NUMBER OF PASSED:" + "\t\t" + passed2.ToString() + Environment.NewLine + "NUMBER OF FAILED:" + "\t" + failed2.ToString();

        foreach (var ch2 in str2)
        {
            var char_by_char2 = ch2;
            Dispatcher.BeginInvoke(new Action(() =>
            {
                second_result.Content += char_by_char2.ToString();
                System.Threading.Thread.Sleep(5);
            }), DispatcherPriority.Background);
        }

Ответы [ 2 ]

0 голосов
/ 17 февраля 2020

Ответ - да.

Но не так, как вы делаете это там.

Диспетчер begininvoke запустит ваше действие в потоке пользовательского интерфейса.

Этот поток - вещь, которая делает все, что связано с пользовательский интерфейс, хотя. Включая вещи, которые вы, вероятно, не хотите прерывать. Как отображение вашего нового персонажа.

Как правило.

Никогда не спите поток пользовательского интерфейса, потому что он замораживает пользовательский интерфейс.

В этом случае «другой» вызов не может ничего сделать, потому что вы записали поток, на котором пытаетесь его запустить. Первый из этих запусков, который запускается, - это то, что какое-то время будет что-то делать, и вы не увидите результаты до его завершения.

Я предлагаю вам удалить строки, имеющие:

  System.Threading.Thread.Sleep(5);

Теперь не будет задержки, но ваш пользовательский интерфейс не будет заморожен.

Сделайте это действие асинхронным c .

Вставьте строку:

await Task.Delay(5);

Где был этот сон.

Как долго вы ожидали задержку?

Это 5 - 5 миллисекунд .

Может быть, вы хотите 500 или 5000.

Затем вы освобождаете эту нить, и у вас должна быть возможность вести себя больше, чем вы ожидали.

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

Затем вы можете выполнить итерацию по await task.delay, чтобы ввести задержку.

0 голосов
/ 17 февраля 2020

Вы не можете вместо этого использовать TPL, например:

var dispatcherObj = Dispatcher.CurrentDispatcher;

string str1 = "NUMBER OF PASSED:" + "\t\t" + passed1.ToString() + Environment.NewLine + "NUMBER OF FAILED:" + "\t" + failed1.ToString();

var tsk1 = Task.Factory.StartNew(()=>
{
    foreach (var ch1 in str1)
    {
        var char_by_char1 = ch1;
        dispatcherObj.Invoke(new Action(() =>
        {                    
            first_result.Content += char_by_char1.ToString();
            System.Threading.Thread.Sleep(5);
        }), DispatcherPriority.Background);
    }
});


string str2 = "NUMBER OF PASSED:" + "\t\t" + passed2.ToString() + Environment.NewLine + "NUMBER OF FAILED:" + "\t" + failed2.ToString();

var tsk2 = Task.Factory.StartNew(()=>
{
    foreach (var ch2 in str2)
    {
        var char_by_char2 = ch2;
        dispatcherObj.Invoke(new Action(() =>
        {
            second_result.Content += char_by_char2.ToString();
            System.Threading.Thread.Sleep(5);
        }), DispatcherPriority.Background);
    }
});

Я запускаю циклы в потоке Task / non UI и публикую изменения пользовательского интерфейса с помощью Dispatcher.Invoke

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...