Reputation: 592
I want to take webcam snapshots on windows with DirectShow. These snapshots will be saved to disk without any display of these images. I want to start the snapshot process that takes a snapshot every second until I stop it, while the main process continues.
So I choose Yet Another Web Camera Control for DirectShow to use it with C#, and the demo works fine.
But I got problem when I use the wrapper in an own task, I get the typical threading error The calling thread cannot access this object because a different thread owns it.
The calling code looks like this:
Task.Run(() =>
{
using (var cam1 = new SnapshotCam(camList.First(), "person", webCameraControl))
{
// Act
Bitmap image = null;
if (!cam1._wcc.IsCapturing)
{
cam1._wcc.StartCapture(cam1._cameraId);
Task.Delay(500).Wait();
}
image = cam1._wcc.GetCurrentImage();
// Assert
Assert.NotNull(image);
}
}).Wait();
The difficult object for me to handle is the webCameraControl
stored in cam1._wcc
: This object inherits from System.Windows.Controls.UserControl
and could be attached to a UI. But in my case I do not have any UI, the snapshots have to be taken in a "headless" style.
So the trouble begins when I want to use the _wcc
-object. I tried already to call the _wcc.Dispatcher
for the corresponding thread but didn't succeed.
How can I call the code above in an own task/thread independent from the rest of the code?
Upvotes: 0
Views: 694
Reputation: 69687
The problem you are hitting immediately is threading related, but eventually it was an unlucky choice of library for webcam capture. You don't need camera frame displaying but the library is implementing taking the stills by rendering video stream to Direct3D device (sort of presentation even if it is "invisible") with copying of last known frame on request.
Perhaps you should rather prefer DxSnap
sample application from DirectShow.NET package. Even though not ideal either:
See also:
Upvotes: 1
Reputation: 52942
If you don't have a UI then you probably don't need to wrap your code in a Task.Run
unless you're trying to do something simultaneously while it's running - and since you're not using await it doesn't /look/ like that's the case.
If you wanted to keep it in a Task.Run then you'd use the Invoke
method on your form, which would allow you to access the camera control in the correct thread, however I don't see how it would solve the problem of running it asynchronously.
If you're not using the control as an actual UI element I don't see why you couldn't create it on a separate thread and use it on that thread, although it doesn't sound like that's how it's intended to be used.
Upvotes: 0