I have an application with a ListView that is generated on Load with times and files to play at those times. I have the following code working on a test machine, but on my development PC (while running from VS) I get a cross-thread error.
My questions are:
1: Any thoughts on why this would this give an InvalidOperationException on the development PC (from VS only, it works fine from the .exe)? Should these subs both have delegates? The error I get from both subs is "Cross-thread operation not valid: Control 'lstSchedule' accessed from a thread other than the thread it was created on."
2: Any suggestions of a better way of using timers run from ListView times other than what I'm doing? The timer here is a System.Threading.Timer.
Public Sub SetNextFileToPlay()
Try
Dim lviTemp As ListViewItem = Me.lstSchedule.Items(IndexToPlayNext)
Dim tcb As TimerCallback = Sub()
'Play the audio file when the timer elapses.
objAudio.PlayMP3(lviTemp)
'After the file plays, set the next timer.
SetNextFileToPlay()
End Sub
'Set the play time 10 minutes ahead, in case we are unable to parse a time from the listview.
Dim dtPlay As DateTime = DateTime.Now.AddMinutes(10)
'Try to parse a time from the listview.
DateTime.TryParse(lviTemp.SubItems(1).Text, dtPlay)
'Ensure that the time is for today so we don't end up with a negative timespan.
dtPlay = New DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, dtPlay.Hour, dtPlay.Minute, dtPlay.Second)
'Subtract the current date/time from the playlist date/time.
Dim execTime As TimeSpan = dtPlay.Subtract(DateTime.Now)
'Create the timer.
tmrMP3 = New Timer(tcb, Nothing, execTime, TimeSpan.Zero)
Catch ex As Exception
oLog.Error("Error playing the file: " & ex.Message)
Finally
IndexToPlayNext += 1
End Try
End Sub
Public Sub PlayMP3(ByRef ListViewItem As ListViewItem)
Try
'Mute the Line In device.
Me.MuteMusic(True)
'Set the file to play.
Dim strFileName As String = String.Empty
Try
strFileName = AUDIO_MP3_PATH & ListViewItem.SubItems(4).Text
If Not File.Exists(strFileName) Then strFileName = AUDIO_MP3_BACKUP_PATH & "blank.wma"
Catch ex As Exception
strFileName = AUDIO_MP3_BACKUP_PATH & "blank.wma"
End Try
'Create a new audio file reader object, so we don't have two files playing over each other.
afrMP3 = Nothing
afrMP3 = New AudioFileReader(strFileName)
wavMP3.Stop()
wavMP3 = Nothing
wavMP3 = New WaveOut
wavMP3.Init(afrMP3)
wavMP3.Play()
'Set the text for the ListViewItem status.
SetListViewItemText(ListViewItem.ListView, ListViewItem.Index, "Playing")
'Break the ListViewItem down into a ListView and index, since you cannot use Invoke on as ListViewItem.
Dim tmpListView As ListView = ListViewItem.ListView
Dim tmpListViewIndex As Int32 = ListViewItem.Index
'When the file stops, unmute the Line In device and set the text for the ListViewItem status.
AddHandler wavMP3.PlaybackStopped, Sub(sender, e) MuteMusic(False)
AddHandler wavMP3.PlaybackStopped, Sub(sender, e) SetListViewItemText(tmpListView, tmpListViewIndex, "Played")
Catch ex As Exception
oLog.Error(ex.Message)
End Try
End Sub