2010-10-31 2 views
1

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

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

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

+1

Invoke или BeginInvoke – CodesInChaos

+1

возможно дубликат [Многопоточность помощь, еще раз (WinForms)] (http://stackoverflow.com/questions/3999020/multithreading-help-yet-again-winforms) –

ответ

4

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

richTextBox1.Invoke(new MethodInvoker(DoSomething)); 

где

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. 
    } 
} 

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

+0

Multumesc mult Vercas! : D Очень подробно! +1 – Alex

+0

oh и другой вопрос! почему эти призывы необходимы? Я имею в виду, какова цель использования такого рода вызовов? Почему я не могу просто позвонить напрямую? – Alex

2

В коде Thread, перед изменением textBox1, проверьте textBox1.InvokeRequired и если да, то используйте textBox1.Invoke(aDelegate)

+0

Я буду искать некоторые ссылки, это Q является обманом. –

+0

поэтому я использовал следующий код: «общественной недействительная SetText (String а) { если (this.richTextBox1.InvokeRequired) { SetTextCallback d = новый SetTextCallback (SetText); this.Invoke (d, новый объект [] {a}); } еще { this.richTextBox1.Text = a; } ' }' – Alex

+0

Мой вопрос: что означает этот код? Что это делает? – Alex

2

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

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

+1 к нему :)

+0

Спасибо за +1! – Vercas

1

Salut ALEXANDRU

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

BackgroundWorker

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

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

найти этот компонент также является очень важным в .NET и очень полезно знать.

+0

multumesc! Я посмотрю! – Alex

+0

Даже если он использовал фона рабочего, он все равно должен будет использовать этот способ для обновления элементов управления. – Vercas

Смежные вопросы