В принципе правильное решение - это события, но когда тебе просто надо обновить прогресс бар, воротить систему событий как-то не хочется, поэтому проще воспользоваться методом Invoke.
Скопировал из своего (Это C#, но суть все равно одна):
public partial class MainForm : Form
{
//Вот сюда стоит обратить внимание
private delegate void LogDelegate(string loginfo, Color clr);
private readonly LogDelegate _logPtr; //readonly не обязательно
public MainForm()
{
_logPtr = Log; //И сюда
}
private void Log(string loginfo, Color clr)
{
textboxLogConnection.SelectionStart = textboxLogConnection.Text.Length;
textboxLogConnection.SelectionColor = clr;
textboxLogConnection.SelectionFont = new Font(textboxLogConnection.SelectionFont, FontStyle.Bold);
textboxLogConnection.AppendText(string.Format("[{0:00}:{1:00}:{2:00}] ", DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second));
textboxLogConnection.AppendText(loginfo + "\n");
}
Далее там где мне надо что-то занести в лог я просто пишу
Invoke(_logPtr, "SOME MESSAGE", Color.Black);
и не парюсь о потоках.