C # событие не обрабатывается - PullRequest
3 голосов
/ 12 февраля 2010

Я изучаю обработку событий C #, написав приложение, которое использует iTunes COM API. У меня есть метод, который должен запускаться, когда iTunes прекращает воспроизведение песни, но метод никогда не вызывается, когда я запускаю событие в приложении, нажимая кнопку «Стоп / Пауза».

РЕДАКТИРОВАТЬ : На основании ответа dboarman я удалил цикл while. Теперь событие обрабатывается, но только если я перезагружаю iTunes перед запуском PlayPlaylist (). Если я запускаю 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).

Spec: мое приложение должно воспроизводить песни в списке воспроизведения рекомендаций Genius от первого до последнего (iTunes по умолчанию не воспроизводит рекомендации Genius последовательно). StopEvent должен запустить следующую песню в списке для воспроизведения.

Ответы [ 4 ]

2 голосов
/ 12 февраля 2010

Вот код complete , о котором идет речь:

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 голос
/ 20 февраля 2010

Когда ваш itapp выходит из области видимости, обязательно выпустите его с

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

или вам придется перезапустить iTunes, чтобы он снова заработал. Отмена регистрации обработчиков событий с - =, вероятно, тоже не повредит.

1 голос
/ 19 февраля 2010

Мне интересно, не вызывает ли тот факт, что обработчик событий не отсоединяется, где-то вдоль линии (т. Е. 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");
    // ...
}
1 голос
/ 12 февраля 2010

Если вы хотите, чтобы поток блокировал и ждал события, вы можете использовать класс 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 (); * +1004 *

Чтобы ответить на ваш первоначальный вопрос, я уверен, что цикл while не дает потоку времени для ответа на событие stop, поэтому вы не видите, как он обрабатывается.

...