0

i have an application which turns your webcam on and off. It turns it on, on a new thread and im trying to make a button work from the main code to turn it off buts cross threading doesnt work and as their is no form, i cant invoke. here is the code:

public class Program
{
    public static FilterInfoCollection CaptureDevicesList;
    public static VideoSourcePlayer videoSourcePlayer = new VideoSourcePlayer();
    public static VideoCaptureDevice videoSource;
    public static System.Timers.Timer TimerClose = new System.Timers.Timer();

    [STAThread]
    static void Main()
    {
        TimerClose.Elapsed += (o, e) => TimerClose_Tick();
        TimerClose.Interval = 10000;
        TimerClose.Start();
        new Thread(() =>
        {
            Thread.CurrentThread.IsBackground = true;
            CaptureDevicesList = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            Class1.oncam();
        }).Start();

        Application.Run();
    }

    private static void TimerClose_Tick()
    {
        Class1.CloseCurrentVideoSource(); // <--- function cant run
    }
}

So what im trying to do is get the close function to work which is trying to turn the webcam off which is running on a different thread. Here is class1:

    class Class1
{
    public static void oncam()
    {
        Program.videoSource = new VideoCaptureDevice(Program.CaptureDevicesList[0].MonikerString);

        OpenVideoSource(Program.videoSource);
    }

    public static void OpenVideoSource(IVideoSource source)
    {
        CloseCurrentVideoSource();

        Program.videoSourcePlayer.VideoSource = source;
        Program.videoSourcePlayer.Start();
    }

    public static void CloseCurrentVideoSource()
    {
        if (Program.videoSourcePlayer.VideoSource != null)
        {
            Program.videoSourcePlayer.SignalToStop();

            for (int i = 0; i < 30; i++)
            {
                if (!Program.videoSourcePlayer.IsRunning)
                    break;
                System.Threading.Thread.Sleep(100);
            }

            if (Program.videoSourcePlayer.IsRunning)
            {
                Program.videoSourcePlayer.Stop();
            }

            Program.videoSourcePlayer.VideoSource = null;
        }
    }
}

Any help is appriciated

Rachel Dockter
  • 946
  • 1
  • 8
  • 21
  • I don't do much with multi-threaded applications aside from services on occasion, but why is every single variable and method you have static? Doesn't that by default raise thread-safety issues? j/w – Lawrence Johnson Aug 28 '16 at 08:55
  • As it relates to your close function, how do you intend to invoke a private method with no call to it? In other words, how are you expecting the close method to be fired? – Lawrence Johnson Aug 28 '16 at 08:57
  • its part of a much bigger program and i was getting all sorts of trouble when they wasnt static so i just changed them all to static, if theres a fix that requires me to change it thats fine – Rachel Dockter Aug 28 '16 at 08:58
  • i have a call for it but i shortened the code, its basicly in a timer, hold on ill add it in – Rachel Dockter Aug 28 '16 at 08:59
  • I see. And in the comment it says "function cannot run", are you getting an error message? If so, can you include it and the stack trace? – Lawrence Johnson Aug 28 '16 at 09:00
  • i edited in the timer that calls it, yes i get the following error "An unhandled exception of type 'System.InvalidOperationException' occurred in AForge.Controls.dll Additional information: Cross thread access to the control is not allowed." – Rachel Dockter Aug 28 '16 at 09:04

1 Answers1

0

VideoSourcePlayer inherits from System.Windows.Forms.Control and thus requires synchronization for cross-thread access.

Call Invoke on this control when accessing it from another thread.

Rotem
  • 21,452
  • 6
  • 62
  • 109
  • can you tell me how i would write it pleae – Rachel Dockter Aug 28 '16 at 09:12
  • There are gazillions of SO questions on that topic, e.g. http://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the – Rotem Aug 28 '16 at 09:13
  • i know but i cant seem to find one in my position. like i can put " Program.Invoke(new MethodInvoker(delegate { WebCam.TurnOffWebCam(); }));" but Program cant invoke, there is no form so im not sure what to put instead – Rachel Dockter Aug 28 '16 at 09:15
  • `videoSourcePlayer.Invoke(...` – Rotem Aug 28 '16 at 09:16
  • Sorry, hard to guess what your whole code looks like. – Rotem Aug 28 '16 at 09:26
  • my mistake that was my fault, it doesnt give me any errors now but when the invoke runs, nothing happens, no errors or anything. idk what im doing wrong – Rachel Dockter Aug 28 '16 at 09:28