Thread in Plugin not Closing (1 Viewer)

hbe02

Portal Member
April 1, 2008
26
1
Home Country
Hi all, Im running a thread in a plugin im making, i want this thread to keep running even when the user switches to another screen. But i also want the thread to be terminated when the user Exits Media Portal.
Right now its working perfectly, but when i exit media portal i still have a thread under "Media Portal" in the running processes under CTRL+ALT+DEL.
I declared the thread as follows:
Code:
ListeningProgram = new Thread(commandsHandler);
            ListeningProgram.Start();
commands handler is a funciton that contains an infinite loop.

So basicly my question is, where do i put the statement:
Code:
ListeningProgram.Abort();

Since i want the thread to keep running even when the user switches to another screen, i assume that i cannot abort the thread in the:
Code:
virtual void OnPageDestroy(int newWindowId)

thanks :-D
 

solis66

MP Donator
  • Premium Supporter
  • January 22, 2007
    141
    20
    Home Country
    Sweden Sweden
    Hi hbe02.

    Perhaps you can do your thread as a process-plugin that always runs when MP is running.
    Then you can interact with this plugin from your Window-plugin to get the information you request.

    If you dont need it to run all the time you can activate it when starting MP and start the executionthread from the windowplugin if you want.

    In this way, the processplugin starts and stops with MP, independent of the window plugin.
    Hopes this helps.
     

    and-81

    Retired Team Member
  • Premium Supporter
  • March 7, 2005
    2,257
    183
    Melbourne
    Home Country
    Australia Australia
    Putting your thread in a process plugin is the best way to have it start and stop when you want.

    But, you should also consider setting:
    thread.IsBackground = true;

    This sounds like you're giving it a lower priority, but what this setting actually does is make the thread terminate if the application terminates. Without setting this the thread will keep running even after the application has stopped (unless you stop it properly yourself, which you should).

    Hope that helps,
     

    solis66

    MP Donator
  • Premium Supporter
  • January 22, 2007
    141
    20
    Home Country
    Sweden Sweden
    Thanks, thats news to me too.
    Always good to learn some new tricks...
     

    hbe02

    Portal Member
    April 1, 2008
    26
    1
    Home Country
    Thank guys!!! it worked!!
    solis66, thanks for the feedback, i think making my program run as a process plugin sounds like a great idea. and would keep everything standardised in MP.
    since i still didnt get into creating process plugins. i tried setting the thread as a background with:
    thread.IsBackground = true;
    worked perfectly fine, and i wish i would have known this property of threads like a year ago because ive had so much trouble terminating threads b4. thanks and-81
    btw, let me explain what im doing. my plugin basically opens a TCP sockets and listens to it in the background waiting for a file path like C:\asong.mp3 .. and then plays it on MP player. well, so far this is what im trying to accomplish but i have a somehow bigger vision for it like networking or voice activation where i could use different languages to interact with that TCP socket, even from a webserver!
    im still having trouble playing the music, but im putting that on a differnt thread :)
     

    and-81

    Retired Team Member
  • Premium Supporter
  • March 7, 2005
    2,257
    183
    Melbourne
    Home Country
    Australia Australia
    I've actually started on a Telnet Interface to MediaPortal ... sounds like we're both doing the same thing ...

    It's still early days but check out the attachment if you're interested. It's accessible on port 2381.

    Cheers,

    PS. Try it out in Hyperterminal and type HELP to get a list of commands.

    Basically you can send actions, jump to a screen, or play a file with it. And it will send you notification of certain events as they occur in mediaportal.
     

    hbe02

    Portal Member
    April 1, 2008
    26
    1
    Home Country
    very impressive code. i see youve made it pretty standardized and professional. my code is not really for normal users so all you do is send a string path file on the TCP socket, the plugin recieves it and simply plays the file.
    check out this post maybe you can help me:
    https://forum.team-mediaportal.com/plugins-47/play-file-37526/

    btw what is GUIWindowManager
    and how does this work:
    GUIWindowManager.SendThreadMessage(message);

    anyways, great job! I also attached a copy of what ive done :)

    [EDIT] okay my university firewall seems to have a problem with me uploading this file.

    until i firgure that out, here is some sample code :
    Code:
      private HDSockets comSocket;
            private Thread ListeningProgram;
            private bool newcommand = false;
            private String FileToPlay;
            private System.Windows.Forms.Timer timer1;
           
    
            public override bool Init()
            {
                return Load(GUIGraphicsContext.Skin + @"\HDMPPlugin.xml");
            }
          
            protected override void OnPageLoad()
            {
                //load listening socket
                comSocket = new HDSockets(4500, HDSockets.ConnectionType.TCP);
                comSocket.Bind();
                comSocket.Listen(5);
    
                //start thread that recieves data
                ListeningProgram = new Thread(commandsHandler);
                ListeningProgram.IsBackground = true;
                ListeningProgram.Start();
    
                //initialize parameters
                newcommand = false;
    
                //initialize timer to play songs
                timer1 = new System.Windows.Forms.Timer();
                timer1.Interval = 1000;
                timer1.Tick += new System.EventHandler(timer1_Tick);
                timer1.Enabled = true;
                //popUp("HD SmartHome Status", "HD SmartHome Has Been Loaded Successfuly");
            }
    
            void commandsHandler(object obj) 
            {
                
                while (true) //loop forever listening for recieved commands
                {
                    HDSockets Client = new HDSockets(4500, comSocket.Accept());   //accept connection and create NetSocket to represetn client
                    ThreadPool.QueueUserWorkItem((new WaitCallback(clientHandler)), Client); //handle client in separate thread
                }
            }
    
            void clientHandler(Object obj)
            { //playing here created alot of problems b/c 
              //media player instance cannot be declared here
                HDSockets Client = (HDSockets)(obj);
                FileToPlay = Client.Recieve();
                newcommand = true;
                Client.Close();
            }
            private void timer1_Tick(object sender, EventArgs e)
            {
                if (newcommand == true)
                {
                    MediaPortal.Player.g_Player.Play(FileToPlay.Trim(), MediaPortal.Player.g_Player.MediaType.Music);
                    newcommand = false;
                }
            }
            private void SendtoVoice(String IP, String Playlist)
            {
                HDSockets initSocket = new HDSockets(4501, HDSockets.ConnectionType.TCP);
                if (initSocket.Connect(IP) == true)
                {
                    initSocket.Send(Playlist);
                    initSocket.Close();
                }
            }
    
    
            protected override void OnClicked(int controlId, GUIControl control,Action.ActionType actionType)
            {
                if (control == buttonOne)
                    OnButtonOne();
              
                base.OnClicked(controlId, control, actionType);
            }
    
            private void OnButtonOne()
            {
                SendtoVoice("127.0.0.1", "Activate");
                popUp("Status", "HD Smart Home Activated Successfuly");
            }
    
            private void popUp(String title, String text)
            {
                GUIDialogOK dlg = (GUIDialogOK)GUIWindowManager.GetWindow(
                (int)GUIWindow.Window.WINDOW_DIALOG_OK);
                dlg.SetHeading(title);
                dlg.SetLine(1, text);
                dlg.SetLine(2, String.Empty);
                dlg.SetLine(3, String.Empty);
                dlg.DoModal(GUIWindowManager.ActiveWindow);
            }

    A few comments on my code, I tried Playing the file directly in my thread that handles socket requests. That didnt work! i cant remember why i debugged it a long time ago. After that i tried playing the file in the Process() function of my plugin. that also backfired and gave me some errors executing after a few times. sorry i dont remember much details. so what i did was make a timer that executes every 0.5 seconds. this timers simply checks if a flag has been change, this flag indicates if a request was recieved in the socket. it anything was recieved it simply plays the file located in a variable that is stored when the plugin recieves the data. yes i thought this approach was a bit eccentric, but.. thats the only was i could make it work that fast:-D
     

    and-81

    Retired Team Member
  • Premium Supporter
  • March 7, 2005
    2,257
    183
    Melbourne
    Home Country
    Australia Australia
    GUIWindowManager is from the MediaPortal core, the SendThreadMessage function just fires a message into MediaPortal for the relevant component to pick up and act on it.

    If you trace the GUIMessage.MessageType.GUI_MSG_PLAY_FILE through the MediaPortal source you'll see where it gets acted on.

    You should definitely change your plugin from Window to Process, this will help a lot.

    I haven't done enough testing on the play file message yet, but I think to use it correctly you need to go to the relevant window first... It's still early days for my Telnet Interface.

    I'll see what I can do with it and then reply on your "Play file" thread.

    Good luck with it all,
     

    hbe02

    Portal Member
    April 1, 2008
    26
    1
    Home Country
    at first i wasnt sure about creating a process plugin. after reviewing you code. I came to an understanding that in order to create a process plugin my class has to inherit from (IPlugin and ISetupForm) just like you have:
    public class TelnetInterface : IPlugin, ISetupForm
    all code under the Isetupform region is as before but the process code should be in the:
    #region IPlugin Members

    from then all i have to code is copy paste the .dll file into the \plugins folder and thats it? is my formulation correct?

    it seems safer to work with GUIWindowManager. i will be checking it out in the next couple of days.

    thanks again:)
     

    and-81

    Retired Team Member
  • Premium Supporter
  • March 7, 2005
    2,257
    183
    Melbourne
    Home Country
    Australia Australia
    yep, it's not hard to turn it into a process plugin. And you will get the advantage that the process plugin's Start and Stop methods get called when MediaPortal starts and stops.

    Cheers,
     

    Users who are viewing this thread

    Top Bottom