Latest Media Handler v2.4.X.000 (4 Viewers)

Sebastiii

Development Group
  • Team MediaPortal
  • November 12, 2007
    16,583
    10,403
    France
    Home Country
    France France
    Yes it will. You cannot update GUI controls in a background thread. If you do, you will get a "Collection changed during enumeration" exception (in the best case) or the "LoadSkin: Running on wrong thread" (worst case). If you are careful you can switch to the main thread only for certain operations that may cause issues and do the rest in the background. However this might not be safe - something that works now may break in the future because of an unexpected change in one of the methods called in the background thread.

    Since in MP1 there is no discrete well defined API and hence no documentation about threading (= guaranteed thread-safety) there is no way to know but to assume pretty much nothing is thread safe.

    Do all your data manipulation in the background then switch to the main thread to talk to GUILib

    PS: MP also has a way to handle executing code on the main thread (events) but it is very cumbersome IMHO. It does however guarantee that the code will be run in a specific sequence in the message loop (before Process() IIRC).

    Hi Arion :)

    What about : https://forum.team-mediaportal.com/...-some-loadskin-error-from-plugin-side.132862/ ?
    I know that Gibman has used it in WIP branch and it fix loadkskin error what i tested it but would like to have your expertise :)
     

    ajs

    Development Group
  • Team MediaPortal
  • February 29, 2008
    16,039
    11,112
    Kyiv
    Home Country
    Ukraine Ukraine
    You cannot update GUI controls in a background thread
    In many situations, I'm just getting the context of the current window (GUIWindow gw = GUIWindowManager.GetWindow(GUIWindowManager.ActiveWindow);), and nothing is updated.
    If you do, you will get a "Collection changed during enumeration" exception (in the best case)
    Never seen such.
    "LoadSkin: Running on wrong thread" (worst case).
    This is an artificial mistake and according to the source code of a purely informational.
    Do all your data manipulation in the background then switch to the main thread to talk to GUILib
    How best to do for individual transactions and not as in the example above (for a procedure)?
     
    Last edited:

    ajs

    Development Group
  • Team MediaPortal
  • February 29, 2008
    16,039
    11,112
    Kyiv
    Home Country
    Ukraine Ukraine
    In LatestMediaHandler.RefreshWorker.OnDoWork() the call to LatestMediaHandler.LatestMyVideosHandler.MyVideosUpdateLatest() should switch to the main thread.
    you can use
    I try:
    Code:
            if (System.Windows.Forms.Form.ActiveForm.InvokeRequired)
            {
              System.Windows.Forms.Form.ActiveForm.Invoke(InitFacade);
            }
            else
            {
              InitFacade();
            }
    But:
    Code:
    (CoreCompile target) ->
      LatestMovingPicturesHandler.cs(474,11): error CS1502: The best overloaded method match for 'System.Windows.Forms.Control.Invoke(System.Delegate)' has some invalid arguments [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
      LatestMovingPicturesHandler.cs(474,55): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Delegate' [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
      LatestMusicHandler.cs(368,11): error CS1502: The best overloaded method match for 'System.Windows.Forms.Control.Invoke(System.Delegate)' has some invalid arguments [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
      LatestMusicHandler.cs(368,55): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Delegate' [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
      LatestMvCentralHandler.cs(246,11): error CS1502: The best overloaded method match for 'System.Windows.Forms.Control.Invoke(System.Delegate)' has some invalid arguments [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
      LatestMvCentralHandler.cs(246,55): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Delegate' [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
      LatestMyFilmsHandler.cs(698,11): error CS1502: The best overloaded method match for 'System.Windows.Forms.Control.Invoke(System.Delegate)' has some invalid arguments [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
      LatestMyFilmsHandler.cs(698,55): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Delegate' [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
      LatestMyVideosHandler.cs(529,11): error CS1502: The best overloaded method match for 'System.Windows.Forms.Control.Invoke(System.Delegate)' has some invalid arguments [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
      LatestMyVideosHandler.cs(529,55): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Delegate' [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
      LatestPictureHandler.cs(902,11): error CS1502: The best overloaded method match for 'System.Windows.Forms.Control.Invoke(System.Delegate)' has some invalid arguments [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
      LatestPictureHandler.cs(902,55): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Delegate' [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
      LatestTVSeriesHandler.cs(691,11): error CS1502: The best overloaded method match for 'System.Windows.Forms.Control.Invoke(System.Delegate)' has some invalid arguments [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
      LatestTVSeriesHandler.cs(691,55): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Delegate' [D:\Work\Programming\C#\LatestMediaHandler\LatestMediaHandler\LatestMediaHandler.csproj]
     

    ajs

    Development Group
  • Team MediaPortal
  • February 29, 2008
    16,039
    11,112
    Kyiv
    Home Country
    Ukraine Ukraine
    You cannot update GUI controls in a background thread
    It seems to me that more true will teach the GUI controls to change ourselves in the right thread, you put the crutches in each plugin.
     

    arion_p

    Retired Team Member
  • Premium Supporter
  • February 7, 2007
    3,373
    1,626
    Athens
    Home Country
    Greece Greece
    In many situations, I'm just getting the context of the current window (GUIWindow gw = GUIWindowManager.GetWindow(GUIWindowManager.ActiveWindow);), and nothing is updated.
    Even so, the above code is not thread safe. What if ActiveWindow changes between the call to GUIWindowManager.ActiveWindow and the call to GUIWindowManager.GetWindow()? What if when you call GUIWindowManager.GetWindow(), GUIWindowManager.Is in the middle of switching windows? (I haven't looked at the code and it's been quite a long time, but my guess is the GetWindow() does more than what is apparent to the eye - eg. actually load the window)

    This is an artificial mistake and according to the source code of a purely informational.
    Not really. It is an error thrown early in the process of LoadSkin to avoid crashing later (which would be harder to recover). Also it warns the developer that he is doing something wrong, which might seem to work if this error was not thrown but may fail unexpectedly (it depends on timing).

    How best to do for individual transactions and not as in the example above (for a procedure)?
    You should avoid too many calls to Control.Invoke(), they are expensive. What Invoke does is it places the delegate in a queue and when the UI thread is idle it will poll that queue and execute the queued delegates. This causes high latency. In the meantime the calling thread is blocked (unless you use BeginInvoke in which case you can do other things in the calling thread and later check the result of the call). You should not use Invoke to call simple methods repeatedly (eg call AddItem() 100 times). i.e.
    Don't do this:
    Code:
    for(i=1; i<100; i++)
    {
      control.Invoke(delegate { list.AddItem(i.ToString()); });
    }
    Do this instead:
    Code:
    control.Invoke(delegate {
      for(i=1; i<100; i++)
      {
        list.AddItem(i.ToString());
      }
    });

    Edit: I am not sure this delegate {} syntax is correct. You may have to use either new MethodInvoker() or new Action()
     
    Last edited:

    arion_p

    Retired Team Member
  • Premium Supporter
  • February 7, 2007
    3,373
    1,626
    Athens
    Home Country
    Greece Greece
    Sorry about my code sample, I did not have time to actually try it and I missed the fact that you need a delegate (or an action)
    You can do this:
    Code:
           if (System.Windows.Forms.Form.ActiveForm.InvokeRequired)
           {
              System.Windows.Forms.Form.ActiveForm.Invoke(new Action(InitFacade));
           }
           else
           {
              InitFacade();
           }
     

    ajs

    Development Group
  • Team MediaPortal
  • February 29, 2008
    16,039
    11,112
    Kyiv
    Home Country
    Ukraine Ukraine
    Even so, the above code is not thread safe. What if ActiveWindow changes between the call to GUIWindowManager.ActiveWindow and the call to GUIWindowManager.GetWindow()? What if when you call GUIWindowManager.GetWindow(), GUIWindowManager.Is in the middle of switching windows? (I haven't looked at the code and it's been quite a long time, but my guess is the GetWindow() does more than what is apparent to the eye - eg. actually load the window)
    Overall, that's okay ... :coffee:
    Sorry about my code sample, I did not have time to actually try it and I missed the fact that you need a delegate (or an action)
    You can do this:
    I will try tomorrow, but anyway, he must control himself to synchronize. Do not plug.
     

    Sebastiii

    Development Group
  • Team MediaPortal
  • November 12, 2007
    16,583
    10,403
    France
    Home Country
    France France
    I have just done something on MP side and for now no more loadskin error when changing skin inside MP for example, based on @arion_p and @gibman code (https://forum.team-mediaportal.com/...n-error-from-plugin-side.132862/#post-1162845).

    I'm not sure if it's ok but i can push the change into the branch for more testing :)

    I changed of LoadSkin load to :

    Code:
    // else load xml file now
          LoadSkin();

    Code:
    // else load xml file now
                    if (System.Windows.Forms.Form.ActiveForm != null && System.Windows.Forms.Form.ActiveForm.InvokeRequired)
                    {
                      GUIWindow._mainThreadContext.Send(delegate
                      {
                        LoadSkin();
                      }, null);
                    }
                    else
                    {
                      LoadSkin();
                    }
     

    ajs

    Development Group
  • Team MediaPortal
  • February 29, 2008
    16,039
    11,112
    Kyiv
    Home Country
    Ukraine Ukraine
    I have just done something on MP side and for now no more loadskin error when changing skin inside MP for example
    How about LMH and FH?
     

    Users who are viewing this thread

    Top Bottom