2015-10-23 3 views
-1

У меня есть программа, которая запускает скошенный передний экран. Я хочу иметь развернутый рекламный цикл видео, который появляется на основе таймера. Я создал отдельную форму для воспроизведения видео и использую таймер, чтобы открыть форму и воспроизвести одно видео, затем я увеличиваю глобальную переменную, закрывая форму, а затем жду, пока таймер снова откроет форму. Когда таймер пытается открыть форму, он дает мне ошибку потока. Я немного новичок в этом уровне кодирования и смущен тем, почему эта ошибка возникает и как ее исправить. Я прочитал эту тему и думаю, что я вообще понимаю проблему, но не могу найти правильный код, чтобы заставить его работать. Вот код (глобальная переменная VAds). Я использовал процедуру вызова, чтобы исправить эту проблему с помощью окна с картинкой, но не могу найти то же самое для видео. Заранее спасибо.Я получаю сообщение об ошибке при попытке открыть форму на основе события отметки таймера

Private Sub PlayAdVideos(sender As Object, e As EventArgs) Handles VideoAds.Click 
     On Error Resume Next 
     If Application.OpenForms().OfType(Of frmAds).Any Then 
      frmVideoAds.Close() 
      Play_Ads.Text = "Start Video Advertisement Loop" 
      Exit Sub 
     Else 
      Play_Ads.Text = "Close Video Advertisement Loop" 
      Dim Sz As Integer 
      If ScreenNo.Text = "" Then 
       Sz = 1 
      Else 
       Sz = ScreenNo.Text 
      End If 

      Dim screen As Screen 
      screen = Screen.AllScreens(Sz) 
      frmVideoAds.StartPosition = FormStartPosition.Manual 
      frmVideoAds.Location = screen.Bounds.Location + New Point(0, 0) 
      frmVideoAds.WindowState = FormWindowState.Maximized 
      frmVideoAds.FormBorderStyle = FormBorderStyle.None 
      frmVideoAds.TopMost = True 
      frmVideoAds.BackColor = Color.Black 
      frmVideoAds.Show() 
     End If 

     For Each foundFile As String In My.Computer.FileSystem.GetFiles("C:\CCHS\VideoAds\") 
      VideoAdList.Items.Add(foundFile) 
     Next 

     If VideoAdList.Items.Count = 0 Then 
      Exit Sub 
     End If 

     Dim TMR2 As New System.Timers.Timer() 

     VideoAdNum = VideoAdList.Items.Count - 1 

     TMR2.Interval = 10000 'miliseconds 
     TMR2.Enabled = True 
     TMR2.Start() 
     AddHandler TMR2.Elapsed, AddressOf OnTimedEvent 

    End Sub 

    Public Sub OnTimedEvent(ByVal sender As Object, ByVal e As ElapsedEventArgs) 

     If frmVideoAds.InvokeRequired Then 
      If VAds = VideoAdNum Then 
       VAds = 0 
      Else 
       VAds = VAds + 1 
      End If 
      frmVideoAds.Invoke(Sub() frmVideoAds.Show()) 
     Else 
      If VAds = VideoAdNum Then 
       VAds = 0 
      Else 
       VAds = VAds + 1 
      End If 
      frmVideoAds.Show() 

     End If 
    End Sub 
+0

Какой язык программирования? Добавьте тег, чтобы сделать его более полезным для других. –

ответ

1

System.Timers.Timer прошло событие, как правило, всегда уволит на потоке, чем в потоке пользовательского интерфейса.

Это означает, что вам нужно будет вызвать frmVideoAds.Invoke каждый раз, когда вы вызываете frmVideoAds.Show() в этом методе.

В вашем другом выражении должно быть просто нужно добавить вызов, что сделает оба пути выполнения одинаковыми, чтобы вы могли обновить все это.

Public Sub OnTimedEvent(ByVal sender As Object, ByVal e As ElapsedEventArgs) 
      If VAds = VideoAdNum Then 
       VAds = 0 
      Else 
       VAds = VAds + 1 
      End If 
      frmVideoAds.Invoke(Sub() frmVideoAds.Show()) 
    End Sub 

Это, как правило, работают, но в некоторых случаях, ActiveX в частности, System.Timers требуется, чтобы быть в однопоточный Апартаменты (STA). По умолчанию используется многопоточная квартира (MTA). Чтобы принудительно включить его в режим STA, просто добавьте

TMR2.SynchronizingObject = Me 

непосредственно перед вашим TM2.Start().

+0

Спасибо, Джеймс. Я пробовал это, но я все еще получаю сообщение об ошибке в строке «frmVideoAds.InvokeRequired». System.InvalidOperationException не был обработан кодом пользователя HResult = -2146233079 Сообщение = Произошла ошибка при создании формы. Подробнее см. Exception.InnerException. Ошибка: ActiveX control '6bf52a52-394a-11d3-b153-00c04f79faa6' не может быть создан, потому что текущая нить не находится в однопоточной квартире. – MPark

+0

, учитывая, что вам требуется Invoke каждый раз, вы можете полностью избавиться от оператора If. После добавления его в Else оба пути выполнения будут одинаковыми. т. е. нет причин проверять, требуется ли ему вызывать, он нужен независимо. –

+0

все еще бросает ошибку. Это правильный синтаксис? Я только что получил обоснованное предположение. 'code' frmVideoAds.Invoke (Sub() frmVideoAds.Show()) – MPark

Смежные вопросы