C# 事件未被处理

发布于 2024-08-21 10:17:05 字数 942 浏览 5 评论 0原文

我正在通过编写一个使用 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 中的源代码此处(第 59-68 行是相关行)。

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

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 song in the list to play.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

要走干脆点 2024-08-28 10:17:05

这是有问题的完整代码:

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

看看这对你有什么作用。

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.

南风几经秋 2024-08-28 10:17:05

当您的 itapp 超出范围时,请务必将其发布,

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

否则您必须重新启动 iTunes 才能再次工作。使用 -= 取消注册事件处理程序可能也不会造成伤害。

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.

佼人 2024-08-28 10:17:05

如果您希望线程阻塞并等待事件,您可以使用 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 循环没有给线程任何时间来响应停止事件,因此您没有看到它被处理。

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.

柠北森屋 2024-08-28 10:17:05

我想知道事件处理程序未取消挂钩是否会导致某个地方出现问题(即 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");
    // ...
}

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");
    // ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文