потому что Вы не связываете свой код с конкретной реализацией списка some_vector. при использовании индексов массива это должна быть некоторая форма массива; при использовании итераторов, можно использовать тот код любой реализации списка.
Я предполагаю, что MyDataReceivedHandler
работает в другом потоке, чем графический интерфейс. Чтобы исправить это, вам необходимо вызвать установщики Text
в правильном потоке. Это пример этого:
public void SetControlText(Control control, string text)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<Control,string>(SetControlText), new object[] { control, text });
}
else
{
control.Text = text;
}
}
private void MyDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
try
{
//sp.PortName = "COM3";
//sp.Open();
SetControlText(Label1, sp.ReadLine());
}
catch (Exception exception)
{
SetControlText(RichTextBox1, exception.Message + "\n\n" + exception.Data);
}
finally
{
sp.Close();
}
}
Если вы используете .NET Framework 2.0, указанный выше делегат Action
недоступен, поэтому вам придется определить свой собственный:
private delegate void SetControlTextHandler(Control control, string text);
public void SetControlText(Control control, string text)
{
if (this.InvokeRequired)
{
this.Invoke(new SetControlTextHandler(SetControlText), new object[] { control, text });
}
else
{
control.Text = text;
}
}
Метод SetControlText
можно сделать короче (и даже статическим) следующим образом (это работает как в 2.0, так и в 3.5):
public static void SetControlText(Control control, string text)
{
´control.Invoke((MethodInvoker)delegate { control.Text = text; });
}
Тогда вам не нужно выполнять проверку InvokeRequired
каждый раз, но вы, с другой стороны, заключите вызов в делегат, даже если он не нужен. Я думаю, что в таком методе графического интерфейса, как этот, любой разницей в производительности между этими двумя нельзя пренебречь, поэтому я предпочитаю использовать более короткую форму,
Вы также можете делать следующее при доступе к элементу управления пользовательского интерфейса из потока, отличного от того, в котором он был создан:
(. NET 3.5)
myControl.BeginInvoke(new MethodInvoker( () => myControl.whatever = whatever; ));
или (.NET 2.0)
myControl.BeginInvoke(new MethodInvoker( delegate { myControl.whatever = whatever; ));
edit> Иногда использование Invoke для длительной операции может / все еще может привести к зависанию пользовательского интерфейса, использование BeginInvoke, очевидно, выполняет эту операцию асинхронно, и пользовательский интерфейс не зависает.