Multi-UI Thread Support
Closed this issue · 7 comments
Hello,
I get an exception when I try to use this library in a separate window that runs on its own thread.
I have tried putting the engine in the constructor of the window so its in the same thread
However that gives me:
If i keep the engine on the main thread by calling it in App, then when I try to use a Player I get the same exception that the current thread does not own the object.
@Wolfleader101 I've never tested with multiple UI threads and not really design for that. So I guess each window will need a different dispatcher pass down to the Player. I will have to review this.
@Wolfleader101 I've never tested with multiple UI threads and not really design for that. So I guess each window will need a different dispatcher pass down to the Player. I will have to review this.
Yea that would probably be the best way. I started looking into how FFMediaElement does it too. If i get a chance to implement the changes into this lib I will make sure to make a PR.
@Wolfleader101 The first question before implementing this is: Why use Multiple UI Threads? I can't see any advantages. The only reason to use them is when you overload the UI thread with things that they shouldn't actually run there. I could understand using async / parallel (Multiple CPU Cores) in "the" UI thread.
In any case it will be difficult to integrate it with the current design / implementation. Currently, it uses the same UI Invoke logic for WinForms/WPF/WinUI 3. Not sure if it will be still possible when using multiple UI threads.
I will try to include this design logic in v4 though.
@Wolfleader101 The first question before implementing this is: Why use Multiple UI Threads? I can't see any advantages. The only reason to use them is when you overload the UI thread with things that they shouldn't actually run there. I could understand using async / parallel (Multiple CPU Cores) in "the" UI thread.
In any case it will be difficult to integrate it with the current design / implementation. Currently, it uses the same UI Invoke logic for WinForms/WPF/WinUI 3. Not sure if it will be still possible when using multiple UI threads.
I will try to include this design logic in v4 though.
Maybe my understand of this is incorrect - but say I have 2 windows in my WPF app, would it not make sense for that 2nd window to have its own UI Thread? Especially if that window contains just say 4 camera streams all running at once in that window.
You don't want any lag caused by the cameras to affect the rest of the app.
@Wolfleader101 Everything in Windows UI (rendering) runs in a single UI thread. The Multiple UI threads are a simulation in .NET not actual UI threads. I guess they did that because a lot of people are messing things with the Invokes/UI Updates with things that take a lot of time while they shouldn't. Even if you have 1K cameras the rendering process should be fast (the preparation/pre-rendering could be slow but this should run on a different non-UI thread)
(I might be wrong but that's my understanding, I will look deeper into it - I've seen that a lot of people - even Microsoft too - they discourage you from using multiple UI threads)
@Wolfleader101 Everything in Windows UI (rendering) runs in a single UI thread. The Multiple UI threads are a simulation in .NET not actual UI threads. I guess they did that because a lot of people are messing things with the Invokes/UI Updates with things that take a lot of time while they shouldn't. Even if you have 1K cameras the rendering process should be fast (the preparation/pre-rendering could be slow but this should run on a different non-UI thread)
Ah ok that makes more sense, so no real gains from running a separate camera window on its own thread....
Like you said assuming the pre-rendering is on its own thread. Ok thank you, i will have to look into that then and give this library another try!
@SuRGeoNix What about something like this
var cameraWindowThread = new Thread(() =>
{
_camWindow = new CameraWindow(vm);
_camWindow .Closed += (s, e) =>
{
_camWindow .Cleanup();
Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);
_camWindow = null;
};
_camWindow .Show();
Dispatcher.Run();
});
cameraWindowThread.Name = $"Camera Window Thread";
cameraWindowThread.SetApartmentState(ApartmentState.STA);
cameraWindowThread.IsBackground = true;
cameraWindowThread.Priority = ThreadPriority.Lowest;
cameraWindowThread.Start();
@Wolfleader101 Closing this for now and I will review it for v4