2010-02-12 3 views
3

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

EDIT: Основываясь на ответе 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 here (строки 59-68 являются значимыми из них).

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

ответ

1

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

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

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

+0

У меня есть следующее: http://ideone.com/UA2D90 Это сокращенный случай. У меня есть мой itunesapp, завернутый синглом, чтобы уменьшить сложность моего приложения. Когда я запускаю приложение, запускаются события воспроизведения/остановки, когда я закрываю приложение с помощью метода закрытия, а затем вручную снова выбираю exe/f5, события не работают ... –

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

еще до того, как перебрать песни в плейлист, возможно, просто удалите весь цикл while. Там нет необходимости сидеть и ждать - предположительно, этот метод вызывается из основного приложения, которое все еще работает? – Dave

+0

+1: хорошая точка о главном приложении ...;) – IAbstract

+0

Спасибо dboarman. Мое намерение с командой «Сон» заключалось в том, чтобы моя программа работала так, чтобы при запуске события процесс прослушивал ее.В противном случае моя программа заканчивается и завершается. Вы видите, что я имею в виду? Есть ли лучший способ достичь этой цели? Я считал дизайн, как тот, который вы предлагаете, но что, если я хочу приостановить мой плейлист вручную? Цикл for будет просто продолжать работать и отменять мою команду. Кроме того, я хочу узнать, что я делаю неправильно, чтобы понять, как работает программирование на основе событий. – RexE

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 не дает нишу в любое время реагировать на событие остановки, следовательно, вы не видите, что это обрабатывается.

+0

+1 nice: Я думал о ManualResetEvent, но у меня все еще есть проблемы с установкой .Set() /. Reset() в нужном месте. Это должно помочь мне запомнить ...;) – IAbstract

+0

Спасибо, Филипп, но я пробовал это, и он все еще не работает, к сожалению. – RexE

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

Итак, * downvoter *, почему downvote более 3 лет спустя? –

+1

Чувак, который был несчастным случаем .. Мне очень жаль .. Если вы отредактируете, я могу удалить проголосовавший голос. –

+0

Прохладный, спасибо. Ред. –