См. Control.Invoke () , который специально разработан, чтобы позволить потокам не-пользовательского интерфейса взаимодействовать с такими вещами, как индикаторы выполнения. В этом случае использование Invoke заменит ваш контекст синхронизации и использование его Send()
метода.
На немного связанной заметке: гораздо более простой способ создать тему:
new Thread(
() => {
/// insert code you want executed in a separate thread here...
}
).Start();
Обновление
Если вам нужно обновить индикатор выполнения из другого класса, я мог бы сделать что-то вроде этого:
public partial class Form1 : Form
{
private ThreadOwner _threadOwner;
public Form1()
{
InitializeComponent();
var _threadOwner = new ThreadOwner();
_threadOwner.StartAThread(this,progressBar1.Minimum,progressBar1.Maximum);
}
protected override void OnClosing(CancelEventArgs e)
{
_threadOwner.Exit();
base.OnClosing(e);
}
internal void SetProgress(int progress)
{
if (progressBar1.InvokeRequired)
{
progressBar1.Invoke(
new Action<Form1>(
(sender) => {
SetProgress(progress);
}
),new[] { this }
);
}
else
progressBar1.Value = progress;
}
}
И класс ThreadOwner:
public class ThreadOwner
{
private bool _done = false;
public void StartAThread(Form1 form, int min, int max)
{
var progress = min;
new Thread(() =>
{
while (!_done)
{
form.SetProgress(progress);
if (progress++ > max)
{
progress = min;
}
}
}
).Start();
}
internal void Exit()
{
_done = true;
}
}
Суть в том, что потоку нужна ссылка на экземпляр формы, который предоставляет метод для обновления индикатора выполнения. Затем этот метод гарантирует, что обновление происходит в правильном потоке.