C#事件未被处理

时间:2010-02-12 05:00:50

标签: c# itunes itunes-sdk

我正在通过编写使用iTunes COM API的应用程序来学习C#事件处理。我有一个应该在iTunes停止播放歌曲时运行的方法,但是当我通过点击“停止/暂停”按钮触发应用程序中的事件时,该方法永远不会被调用。

编辑:根据dboarman的回复,我删除了while循环。现在事件确实得到了处理,但前提是我在运行PlayPlaylist()之前重新启动iTunes。如果我第二次运行PlayPlaylist(),则不再触发/处理停止事件。

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");
    //...
}

更新了Pastebin here中的来源(第59-68行是相关的)。

规格:我的应用程序应该从头到尾播放Genius推荐播放列表中的歌曲(默认情况下,iTunes不会连续播放Genius推荐)。 StopEvent应该触发列表中的下一首歌曲。

4 个答案:

答案 0 :(得分:2)

以下是有问题的完整代码:

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);
    }
}

我怀疑while循环导致事件永远不会触发,因为线程会休眠一秒钟,因为true是......总是如此。

我会将您的播放列表放入列表中。类似的东西:

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
    }
}

了解这对您有何帮助。

答案 1 :(得分:1)

如果您希望线程阻塞并等待事件,您可以使用ManualResetEvent类。

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); 
}

在itapp_OnPlayerStopEvent()内你必须调用:   _resetEvent.Set();

要回答你的原始问题,我很确定while循环没有给线程任何时间来响应停止事件,因此你没有看到它被处理。

答案 2 :(得分:1)

我想知道事件处理程序没有取消挂钩这一事实是否导致了某个地方的问题(即iTunes拥有对应用程序初始实例的单一引用)。这个可能解决了吗?我没有iTunes API,所以我有点失明;如果这是浪费时间,请道歉。

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");
    // ...
}

答案 3 :(得分:1)

当你的itapp超出范围时,请务必使用

释放它
System.Runtime.InteropServices.Marshal.ReleaseComObject(itapp);

或者您必须重新启动iTunes才能再次使用它。使用 - =取消注册事件处理程序也可能不会受到影响。