2010-09-04 1 views
0

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

Этот код добавляет thread.sleep (500), чтобы поддерживать работоспособность, читает из COM-порт некоторые вызовы и отправляет сигнал тревоги другим ПК сейчас на этот раз, когда я отправлял некоторую информацию на рассматриваемый аппарат эта ошибка появляется

Неверное выполнение кросс-потоков: элемент управления 'textBox1' доступен из потока, отличного от потока, на котором он был создан.

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) { 
     Thread.Sleep(500); 
     string data = port.ReadExisting(); 
     //try 
     //{ 
      if (textBox1.TextLength == 30000) 
      { 
       textBox1.Text = ""; 
      } 
     //} 
     //catch (Exception) {} 
     this.BeginInvoke(new setTextDeleg(si_DataRecived), new object[]{ 
     data}); 
    } 

Это функция, которая пишет на ком машину, делает что делает исключение есть ошибка в порядке, или есть еще лучший способ справиться с этим?

PD: Извините за мой плохой английский, это на C# 2008 против

+0

Вы уже используете BeginInvoke, как и вы, я не понимаю смысла. Вызов Sleep() * очень * уродливый, на самом деле он не является надежным. Просто будьте аккуратны. –

+0

Я предполагаю, что я сделал этот код несколько лет назад, я просто обновляю его, но я согласен, у меня есть вопрос, порт com виртуализирован, если я удалю thread.sleep, кажется, он пытается вернуться к com1 по какой-либо причине идея почему? – Enrique

ответ

1

Вы должны модифицировать компоненты GUI, такие как текстовые поля и этикетки только из потока, создавшего их, которая является основной поток. Вы можете взглянуть на BackgroundWorker, что упрощает эту задачу в приложении WinForms. И вот еще один useful article, иллюстрирующий использование свойства InvokeRequired и метода Invoke.

0

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

+0

Спасибо, что это похоже на то, что мне нужно. – Enrique

0

Проблема заключается в том, что элементы управления Windows Forms не являются потокобезопасными, и кажется, что элемент управления не запускается правильно для поточно-безопасного вызова. Вы можете использовать класс BackgroundWorker, или вы можете invoke его самостоятельно. Вот пример небольшого кода.

// Delegate used by our worker thread to invoke our control 
    private delegate void ProgressDelegate(int value); 

    // Callback method used for our delegate 
    private void ProgressCallback(int value) { 
     progressBar1.Value = value; 
    } 

    protected override void OnShown(EventArgs e) { 
     Thread thread = new Thread(new ThreadStart(MyThreadWorker)); 
     thread.IsBackground = true; 
     thread.Start(); 
    } 

    // Thread method 
    private void MyThreadWorker() { 
     // Setup the delegate 
     ProgressDelegate mydelegate = new ProgressDelegate(ProgressCallback); 

     // Do some work 
     int pos = 0; 
     do { 
      pos++; 

      // Make a thread-safe call to our control and invoke our callback on the original thread 
      // Original thread: The thread the form and control were created on 
      progressBar1.Invoke(mydelegate, pos); 
     } while (pos < 100); 
    } 
0

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

if (textBox1.TextLength == 30000) 
     { 
      textBox1.Text = ""; 
     } 

к методу si_DataRecived, так что она будет выполнена как часть BeginInvoke вызова, цель которого будет выполняться в основном потоке (UI).

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