开发者

C# event not being handled

开发者 https://www.devze.com 2022-12-20 10:50 出处:网络
I\'m learning C# event handling by writing an app that uses the iTunes COM API. I have a method that should run when iTunes stops playing a song, but the method is never getting called when I trigger

I'm learning C# event handling by writing an app that uses the iTunes COM API. I have a method that should run when iTunes stops playing a song, but the method is never getting called when I trigger the event in the app by hitting the "stop/pause" button.

EDIT: Based on dboarman's reply, I deleted the while loop. Now the event does get handled, but only if I restart iTunes prior to running PlayPlaylist(). If I run PlayPlaylist() a second time, the stop event no longer gets fired/handled.

void trayIcon_Click(object sender, EventArgs e)
{
    PlayPlaylist();
}

public static void PlayPlaylist()
{

    itapp = new iTunesApp();
    itapp.OnPlayerStopEvent += 
        new _IiTunesEvents_OnPlayerStopEventEventHandler(itapp_OnPlayerStopEvent);

    lastPlaylist = itapp.LibraryPlaylist;

    itapp.Play();            
}

static void itapp_OnPlayerStopEvent(object iTrack)
{
    Debug.WriteLine("Stop Event fired");
    //...
}

Updated source in Pastebin here (lines 59-68 are the relevant ones).

Spec: My app is supposed to play the songs in a Genius recommendations playlist from first to last (iTunes by default doesn't play Genius recommendations consecutively). The StopEvent should trigger the next so开发者_JAVA百科ng in the list to play.


Here is the complete code that is in question:

public static void PlayPlaylist()
{
    itapp = new iTunesApp();
    itapp.OnPlayerStopEvent += new _IiTunesEvents_OnPlayerStopEventEventHandler(itapp_OnPlayerStopEvent);

    lastPlaylistID = itapp.LibraryPlaylist.playlistID;
    Debug.WriteLine("Last playlist:");
    Debug.WriteLine(lastPlaylistID);

    itapp.Play();

    while (true)
    {
        System.Threading.Thread.Sleep(1000);
    }
}

I suspect that the while loop is causing the event to never fire because the thread will sleep for a second and because true is, well...always true.

I would put your playlist in into a list. Something like:

static List<myTrack> Tracks;

public static void PlayPlaylist() 
{
    itapp = new iTunesApp();
    itapp.OnPlayerStopEvent += new _IiTunesEvents_OnPlayerStopEventEventHandler(itapp_OnPlayerStopEvent);

    foreach (myTrack track in Tracks)
    {
    // perform play
    }
}

See how that works for you.


When your itapp goes out of scope, be sure to release it with

System.Runtime.InteropServices.Marshal.ReleaseComObject(itapp);

or you'll have to restart iTunes for it to work again. Unregistering the event handlers with -= probably wouldn't hurt either.


If you want the thread to block and wait for the event you can use the ManualResetEvent class.

private ManualResetEvent _resetEvent;

public void PlayPlaylist() 
{
    _resetEvent = new ManualResetEvent(false);
    itapp = new iTunesApp();
    itapp.OnPlayerStopEvent += new _IiTunesEvents_OnPlayerStopEventEventHandler(itapp_OnPlayerStopEvent);


    // Block until the resetEvent has been Set() or
    // give up waiting after 5 minutes
    _resetEvent.WaitOne(1000*5*60); 
}

Inside itapp_OnPlayerStopEvent() you must call: _resetEvent.Set();

To answer your original question, I'm pretty sure the while loop is not giving the thread any time to respond to the stop event, hence you are not seeing it being handled.


I'm wondering if the fact that the event handler doesn't unhook is causing an issue somewhere along the line (i.e. iTunes holds a singular reference to the initial instance of your app). This may solve it? I don't have the iTunes API so I'm flying a little blind; apologize if it's a waste of time.

private bool stopIt;

private void trayIcon_Click(object sender, EventArgs e)
{
    if (!stopIt)
    {
        PlayPlaylist();
        stopIt = true;
    }
    else
    {
        StopPlaylist();
        stopIt = false;
    }
}

public static void PlayPlaylist()
{

    itapp = new iTunesApp();
    itapp.OnPlayerStopEvent += 
        new _IiTunesEvents_OnPlayerStopEventEventHandler(itapp_OnPlayerStopEvent);

    lastPlaylist = itapp.LibraryPlaylist;

    itapp.Play();            
}

public static void StopPlaylist()
{
    itapp.Stop(); // don't know if this is the right method name

    // unhook the event so the reference object can free if necessary.
    itapp.OnPlayerStopEvent -= 
        new _IiTunesEvents_OnPlayerStopEventEventHandler(itapp_OnPlayerStopEvent);
}

private static void itapp_OnPlayerStopEvent(object iTrack)
{
    Debug.WriteLine("Stop Event fired");
    // ...
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号