Как справиться с ошибкой перекрестного потока в приложении C Sharp для Windows? - PullRequest
0 голосов
/ 02 ноября 2011

У меня есть приложение с индикатором выполнения и кнопкой.

При нажатии кнопки значение индикатора выполнения увеличивается, вот исходный код,

private void Run()
        {               
                progressBar1.Maximum = 1000;
                progressBar1.Minimum = 0;
                progressBar1.Step = 1;

                for (int l_nIndex = 0; l_nIndex < 1000; l_nIndex++)
                {
                        progressBar1.Value++;
                        Thread.Sleep(10);
                }
            }


private void button1_Click(object sender, EventArgs e)
        {
                Run();
    }

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

Я не могу запустить его обычным способом - он выдаст ошибку Cross-Thread.

поэтому я изменил код как,

private void Run()
        {
                if (this.InvokeRequired)
                {
                    this.Invoke(new MethodInvoker(this.Run));
                }
                else
                {
                    progressBar1.Maximum = 1000;
                    progressBar1.Minimum = 0;
                    progressBar1.Step = 1;
                    for (int l_nIndex = 0; l_nIndex < 1000; l_nIndex++)
                    {
                            progressBar1.Value++;
                            Thread.Sleep(10);
                    }
                }
        }

 private void button1_Click(object sender, EventArgs e)
        {
                Thread myThread = new Thread(new ThreadStart( Run));
              myThread.Start();
        }

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

Ответы [ 2 ]

3 голосов
/ 02 ноября 2011

На это ответили здесь - в вашем случае код должен выглядеть примерно так:

this.BeginInvoke((Action)(() => progressBar1.Value++));
3 голосов
/ 02 ноября 2011

Invoke() работает путем запуска данного делегата из потока пользовательского интерфейса. Так что если вы используете Invoke() для запуска всего метода , тогда весь ваш метод запускается из потока пользовательского интерфейса.

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

Один из простых способов сделать это - использовать класс BackgroundWorker, встроенный в стандартную библиотеку.

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