Reputation: 1633
I have MainForm
class and some Engine
class for camera control. In Engine
class, I have some Camera
object, which is part of SDK from camera producer.
This Camera
has available OnNewFrame
event, so I'll initialize:
camera.OnNewFrame += frameAcquired;
frameAcquired
is also member of Engine class.
private void frameAcquired(object sender, EventArgs e)
{
/* this event should periodically raise after ~17ms,
but sometimes it hangs for a short time
(when I overloads main thread) */
}
The Engine
object is a member of MainForm
class. Here I am displaying images from camera and doing some other graphics stuff. The problem is that MainForm
thread sometimes hangs for a very short time. It's not so critical for displaying, but it is for camera.OnNewFrame
event (I'm working with 60 fps), as this is also delayed because of main thread delay.
Is it possible to ensure some way, that Engine
object (or Camera
object in Engine
) will raise event's from it's own thread, not from main thread? Other words, ensure that this event raises in rate which SDK producer has set, not dependent on my main thread.
Upvotes: 0
Views: 1842
Reputation: 66
I have ran into a similar problem not too long ago. I have dealt with it in C++/CLI so the same approach should also work in C# too.
I believe you have the Engine class initialized in your MainForm. If you want to raise events from another thread then this object has to be initialized in another thread.
I believe you should try creating a new Thread in your MainForm constructor:
MyForm()
{
//rest of your constructor
cameraThread = new Thread(new ParameterizedThreadStart(CameraRun));
cameraThread.Name = "Camera Thread";
cameraThread.Start(this);
while (!cameraThread.IsAlive)
Thread::Sleep(1);
}
This way you can keep a field for cameraThread in your MyForm class. Still, you need to write a function for the new thread to run. We know it will initialize your Engine class but that is not all. Just to make sure the thread doesn't finish the function you gave it to run, add some check at the bottom of thread function like this:
void CameraRun(Object myForm)
{
//you can use (myForm as MyForm)
//and make calls from here
/*
Engine initialization etc
*/
while((myForm as MyForm).isShown)
Sleep(100);
}
cameraThread should join back to your main code in MainForm destructor.
~MyForm()
{
//rest of your destructor
this.isShown=false;
cameraThread.Join();
}
You can put the line this.isShown=false to your OnFormClosed() event if you wish.
If you have come this far, great. However you are not done yet, unfortunately. As you are now working on multiple threads you have to make sure you access objects in a thread safe manner. Long story short, check this answer.
Edit: some corrections
Upvotes: 1