sub Wrote:Unfortunately no there isnt. The next version does have an event notification to let apps know that it's exiting though.
Does 1.2.9 include this event notification? I couldn't see the event in GBPVR.Public.EventTypes, and nothing seems to be sent to IEventNotification. Am I doing someting wrong?
[SIZE="1"]Silverstone GD01S-MXR (three dead rows of pixels in the LCD and defective remote control), Power: Zalman ZM460B-APS (blew up - can't remember what's there now); CPU: Pentium D 3.2 GHz with Asus V72 Cooler; MD: Asus P5LD2 Deluxe 2048MB,
WDC WD10EADS 1TB Data, 320GB System, Asus EN9400GT Silent 512MB, Hauppauge HVR 1300,
XP Home SP3, GB-PVR 2.0, ExternalDisplay v0.3[/SIZE]
Sorry, no it didnt get included in 1.2.9. I realised there would be some situations where the app wasnt going to know it was exiting, so I talked to whurlston and we solved his particular problem a different way.
whurlston Wrote:sub is too kind. I was not setting isBackground = true on my threads so they were not closing with GB-PVR.
The thread.isBackground=true does allow the termination of the plugin when PVRX2 exits as mentioned previously, however, I am having some difficulties in getting the ExternalDisplay plugin to terminate properly by executing some cleanup code. Hopefully, the gurus out there can provide some guidance on what's wrong with the code
in pseudo code
Code:
public class GBPVRStopPluginTestTask: IEventNotification
{
public GBPVRStopPluginTestTask()
{
if (PluginHelperFactory.getPluginHelper() == null ) return;
DoStart();
// set up a 'do nothing' Timer to keep this running in the same thread, and allow the destructor to be caught on class exit - This is the only way I was able to get the plugin to terminate
System.Timers.Timer NullTimer = new System.Timers.Timer(60000);
NullTimer.Elapsed += new System.Timers.ElapsedEventHandler(DoNothing);
NullTimer.Start();
NullTimer.Enabled = true;
return;
}
/// <summary>
/// This 'Do Nothing' method is just to keep the main thread running
/// so that the Destructor is called when t.Isbackround=true.
/// </summary>
private void DoNothing(object sender, EventArgs e)
{
return;
}
~GBPVRStopPluginTestTask()
{
// This is only called if the doNothing method is used, and IsBackground=true
Stop();
}
public void DoStart()
{
// startup code
stopRequested = false;
t = new Thread(new ThreadStart(Run));
t.Priority = ThreadPriority.Lowest;
t.IsBackground=true;
t.Name = "StopPluginTest";
t.Start();
}
public void Run()
{
while (!stopRequested)
{
// This is where the work is done
// DoWork();
Thread.Sleep(250);
}
// clean up code
}
private void Stop()
{
stopRequested = true;
while (t.IsAlive)
{
Logger.Verbose("StopPluginTest.DoStop(): Background thread still alive, waiting 100ms...");
Thread.Sleep(100);
}
t = null;
// cleanup code
}
}
}
Debugging suggest that when PVRX2 exits, the class destructor gets called, and the Stop() method is correctly called.
Although stopRequested is set to true by Stop(), the while(!stopRequested) loop in Run() does not appear to exit, and the cleanup code in the Run() never gets to execute. It appears as though this thread simply terminates, rather than exiting the loop, and then running the cleanup code.
But t.IsAlive in Stop() continues to return âtrueâ, so Stop() loops several 100âs ms, and never gets to run any of the cleanup code because it never breaks out of the while(t.IsAlive) loop.
Iâve lost count of the different combinations of threads and isBackgound=true/false Iâve tried. Perhaps Iâm stuck in the trees and forgotten what the forest is supposed to look like and thereâs something fundamental thatâs not being done correctly.
Compilable code with some extras:
[SIZE="1"]Silverstone GD01S-MXR (three dead rows of pixels in the LCD and defective remote control), Power: Zalman ZM460B-APS (blew up - can't remember what's there now); CPU: Pentium D 3.2 GHz with Asus V72 Cooler; MD: Asus P5LD2 Deluxe 2048MB,
WDC WD10EADS 1TB Data, 320GB System, Asus EN9400GT Silent 512MB, Hauppauge HVR 1300,
XP Home SP3, GB-PVR 2.0, ExternalDisplay v0.3[/SIZE]