Доступ к данным в другом потоке - PullRequest
1 голос
/ 31 октября 2010

У меня есть winform и некоторые темы. Когда я пытаюсь получить доступ к полю в winform из одного из потоков, возникает следующая ошибка: Cross-thread operation not valid: Control 'richTextBox1' accessed from a thread other than the thread it was created on.

Как я могу решить эту проблему?

С уважением, Александру Бадеску

Ответы [ 4 ]

4 голосов
/ 31 октября 2010

Все элементы управления имеют метод Invoke, который принимает делегат в качестве первого аргумента и необязательный объект params [] .
Этот метод можно легко использовать:

richTextBox1.Invoke(new MethodInvoker(DoSomething));  

where

void DoSomething()
{
    richTextBox1.BackColor = Color.Cyan;
}

Делегат MethodInvoker находится в пространстве имен System.Windows.Forms, которое, я полагаю, вы уже используете.

Вы даже можете вызвать из того же потока!

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

richTextBox1.Invoke(new ColorChanger(DoSomething), Color.Cyan);  

, где

delegate void ColorChanger(Color c);

void DoSomething(Color c)
{
    richTextBox1.BackColor = c;
}

Надеюсь, это помогло!

Редактировать:
InvokeRequired требуется, если вы используете тот же метод из ... в основном ... неизвестного потока.Так это будет выглядеть так:

void DoSomething()
{
    if (richTextBox1.InvokeRequired)
        richTextBox1.Invoke(new MethodInvoker(DoSomething));
    else
    {
        richTextBox1.BackColor = Color.Cyan;
        // Here should go everything the method will do.
    }
}

Вы можете вызывать этот метод из ЛЮБОГО потока!

А для параметров:

delegate void ColorChanger(Color c);

void DoSomething(Color c)
{
    if (richTextBox1.InvokeRequired)
        richTextBox1.Invoke(new ColorChanger(DoSomething), c);
    else
    {
        richTextBox1.BackColor = c;
        // Here should go everything the method will do.
    }
}

Наслаждайтесь программированием!

2 голосов
/ 31 октября 2010

То, что предложил Vercas, работает нормально, но если вы любите встроенный код, вы также можете попытаться выбрать анонимного делегата

richTextBox1.Invoke(new MethodInvoker(
    delegate() {
        richTextBox1.BackColor = Color.Cyan;
    ));

+ 1 ему:)

2 голосов
/ 31 октября 2010

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

1 голос
/ 31 октября 2010

Salut Alexandru

Возможно, вы захотите проверить альтернативный способ, компонент

BackgroundWorker

.Это действительно легко и удобно в использовании.Более подробную информацию и образцы вы можете найти здесь

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

Этот компонент также очень важен в .NET и очень полезен для ознакомления.

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