Если вы хотите добавить элемент в последнюю позицию списка, вы можете попробовать: list.insert(END, item)
self.recievingAdress.insert(END, "apple")
Вы не можете получить доступ к элементам UI от нескольких потоков.
Один способ решить это состоит в том, чтобы назвать Вызвать метод управления с делегатом в функции, которые используют элементы UI (как окно сообщения). Somethin как:
public delegate void InvokeDelegate();
public void SomeMethod()
{
button1.Invoke((InvokeDelegate)doUIStuff);
}
void doUIStuff()
{
MessageBox.Show(this,
ex.Message,
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
}
для предотвращения исключений перекрестного потока (InvalidOperationException) вот, шаблон кода:
protected delegate void someGuiFunctionDelegate(int iParam);
protected void someGuiFunction(int iParam)
{
if (this.InvokeRequired)
{
someGuiFunctionDelegate dlg = new
someGuiFunctionDelegate(this.someGuiFunction);
this.Invoke(dlg, new object[] { iParam });
return;
}
//do something with the GUI control here
}
я соглашаюсь, что это является раздражающим, но это - артефакт того, что средства управления окнами GUI не ориентированы на многопотоковое исполнение. Исключение может быть выключено с флагом где-нибудь или другим, но не делает этого, поскольку оно может привести к чрезвычайно трудно для нахождения ошибок.
Для хранения вещей простыми, можно изучить использование класса BackGroundWorker. Этот класс будет служить основой для обработать Вашу поточную обработку и события уведомления о прогрессе. Ваш поток ui обработает событие прогресса и отобразит сообщение об ошибке, которое Вы пасуете назад.
ИЛИ
Правило номер один, когда многопоточность - Вы абсолютно, не может коснуться UI от рабочих потоков. Существует много способов реализовать многопоточность, и очень трудно разобраться в нем.
Вот сжатая статья, которая должна выручить Вас - Обновление UI от Вторичного Потока
И вот длинная статья, которая обсуждает всестороннюю поточную обработку - Многопоточность в.NET
Вы не должны использовать BeginInvoke, необходимо использовать, Вызывают, затем после того как Вы осознаете, что, можно изучить использование BeginInvoke, если действительно необходимый.
'*******************************************************************
' Get a new processor and fire it off on a new thread.
'*******************************************************************
fpProc = New Processor(confTable, paramFile, keyCount)
AddHandler fpProc.LogEntry, AddressOf LogEntry_Handler
Dim myThread As System.Threading.Thread = New System.Threading.Thread(AddressOf fpProc.ProcessEntry)
myThread.Start()
Затем в родительском приложении Вы имеете:
'*************************************************************************
' Sub: LogEntry_Handler()
' Author: Ron Savage
' Date: 08/29/2007
'
' This routine handles the LogEntry events raised by the Processor class
' running in a thread.
'*************************************************************************
Private Sub LogEntry_Handler(ByVal logLevel As Integer, ByVal logMsg As String) Handles fProc.LogEntry
writeLogMessage(logMsg);
End Sub
Это - то, что я делаю.
Я, в сущности, похож на рекурсивный вызов.
public delegate void InvokeDelegate(string errMessage);
public void SomeMethod()
{
doUIStuff("my error message");
}
void doUIStuff(string errMessage)
{
if (button1.InvokeRequired)
button1.Invoke((InvokeDelegate)doUIStuff(errMessage));
else
{
MessageBox.Show(this,
ex.Message,
errMessage,
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
}
}