Reputation: 423
I'm currently trying to create a timer that will run a chunk of code every few milliseconds. the problem is i want to be able to Modify the position of a picture box that is created on the same thread as the timer, I end up getting the Invoke object error even though its not created on the original thread ?
private void frmMain_Load(object sender, EventArgs e)
{
//Update Timer Thread
UpdateThread = new Thread(new ThreadStart(UpdateWindow));
SleepTime = (int)1000/MaxFps;
UpdateThread.Start();
//.....
}
delegate void SetTextCB(string text);
delegate void SetControl(Control cntrl);
public void TimerThread()
{
//Controls
PictureBox TestPicBox;
//Test TestPicBox
TestPicBox = new PictureBox();
TestPicBox.Image = Image.FromFile(TestImage.bmp");
TestPicBox.Top = 20;
TestPicBox.Left = 20;
TestPicBox.Width = 64;
TestPicBox.Height = 64;
FilePanelControl(TestPicBox);
while (true)
{
//--Sleep
Thread.Sleep(SleepTime);
//--FPS
if (DateTime.Now.ToString("HH:mm:ss") != SystemTime)
{
if (blnShowFps) { lblFpsTextsSet(UpdateFps.ToString() + "-FPS"); }
else { lblFpsTextsSet(""); }
SystemTime = DateTime.Now.ToString("HH:mm:ss");
UpdateFps = 0;
}
UpdateFps++;
//Sleep Time
SleepTime = (int)1000 / MaxFps;
//Do UpDate Logic
TestPicBox.location = new point(10,10);
}
}
//--Add Control
private void FilePanelControl(Control added)
{
if (this.FilePanel.InvokeRequired)
{
SetControl d = new SetControl(FilePanelControl);
this.Invoke(d, new object[] { added });
}
else
{
this.FilePanel.Controls.Add(added);
}
}
//--lblFps.text
private void lblFpsTextsSet(string text)
{
if (this.lblFPS.InvokeRequired)
{
SetTextCB d = new SetTextCB(lblFpsTextsSet);
this.Invoke(d, new object[] { text });
}
else
{
this.lblFPS.Text = text;
}
}
hoping i don't have to invoke every control i declare on this thread as the plan was to make a picture box list, so the user could add picture boxes as needed.
Thanks For the help.
Upvotes: 3
Views: 1315
Reputation: 3965
The same InvokeRequired
and Invoke
(or BeginInvoke
) should be used to set PictureBox.Location
. Control properties must be set on the thread where the control handle was created, that is decided by WinForms, not where the control itself was created.
The reasons are explained in Control.InvokeRequired.
Here is more information on multithreading in Windows Forms Controls that includes an example of using a background thread.
Upvotes: 1
Reputation: 887767
You should use a System.Windows.Forms.Timer instead of creating your own thread.
This way, everthying will already be on the UI thread.
Upvotes: 3