2016-04-12 12 views
1

habe ich diesen Code:Vermeiden Ausführung Überlappung

Private Sub NewRecallLabel_TextChanged(sender As Object, e As EventArgs) 
    Dim myrecalllabel As Label = TryCast(sender, Label) 

    Dim SpeechSynthesizer As New SpeechSynthesizer 

    SpeechSynthesizer.Speak("Ticket number " & TTSTicket & ", please proceed to counter " & TTSCounter) 

End Sub 

Was passiert, ist, wenn das Textchanged-Ereignis ausgelöst wird, die UI friert während des Sprech Code auszuführen. Ich weiß mit SpeakAsync wird das Problem lösen, aber wenn mehrere TextChanged Ereignis ausgelöst wird, überlappt das Audio - ich will nicht, dass das passiert.

Kann mir jemand zeigen, wie ich das vermeiden könnte?

+0

möglicherweise dasselbe wie [dies] (http://stackoverflow.com/questions/17419961/c-sharp-threadpool-queueuserworkitem-use) – carlot0820

+0

Welche .NET-Version zielen Sie ab? –

+0

Ich ziele auf .NET v4 Sir. – carlot0820

Antwort

0

vielleicht mit asynchronem Aufruf mit Sperre wird dazu beitragen, es würde wie folgt aussehen:

Private Sub NewRecallLabel_TextChanged(sender As Object, e As EventArgs) 
    Dim myrecalllabel As Label = TryCast(sender, Label) 
    Dim SpeechSynthesizer As New SpeechSynthesizer 
     SpeechSynthesizer.SpeakAsync("Ticket number " & TTSTicket & ", please proceed to counter " & TTSCounter) 
End Sub 

In Ihrer Async Anruf Verwendung lock:

Private messagesLock As New Object 
SyncLock messagesLock 
    SpeechSynthesizer.Speak("the sync one") 
End SyncLock 

ich dies nicht versuchen, aber Sie bekommen die Idee .

1

Wir haben festgestellt, dass Sie .NET 4.0 verwenden, so dass SemaphoreSlim das Fenster ausgeht.

Zuerst würde ich versuchen, um das Problem immer durch eine Instanz von SpeechSynthesizer teilen und SpeakAsyncCancelAll zu verwenden, wenn eine neue Anforderung kommt:

Private SpeechSynthesizer As New SpeechSynthesizer 

Private Sub NewRecallLabel_TextChanged(sender As Object, e As EventArgs) 
    Dim myrecalllabel As Label = TryCast(sender, Label) 

    SpeechSynthesizer.SpeakAsyncCancelAll() 
    SpeechSynthesizer.SpeakAsync("Ticket number " & TTSTicket & ", please proceed to counter " & TTSCounter) 
End Sub 

oringinal antworten

Da Sie nicht verwenden können, SyncLock in einem asynchronen Kontext und Sie wollen nicht-blockierende Ausführung, Ihre beste Wette ist es, eine SemaphoreSlim(1, 1) zu verwenden, um asynchrone Mutex-Semantik zu erhalten (ähnlich wie @Gubr vorgeschlagen, außer async):

Private Semaphore As New SemaphoreSlim(1, 1) 

Private Sub NewRecallLabel_TextChanged(sender As Object, e As EventArgs) 
    Dim myrecalllabel As Label = TryCast(sender, Label) 
    Dim SpeechSynthesizer As New SpeechSynthesizer 

    Await Semaphore.WaitAsync() 

    Try 
     ' We're inside the protected region now. 
     Await SpeechSynthesizer.SpeakAsync("Ticket number " & TTSTicket & ", please proceed to counter " & TTSCounter) 
    Finally 
     Semaphore.Release() 
    End Try 

End Sub 

ich auch Verdrahtung in irgendeiner Form der Drosselung betrachten würde und/oder Auto-Löschung, da der Code, wie es will steht nicht Arbeit sehr gut, wenn die Beschriftung schnell ändert (d Jede weitere Sprachanfrage muss auf die vorherigen Sprachanforderungen warten.

+0

Ich dachte, es wird funktionieren, da Lock-Anweisung in eine normale synchrone Methode eingewickelt wird, die asynchron aufgerufen wird. Aber vielleicht lag ich falsch, als ich sagte, ich habe es nicht wirklich versucht. Ihre Lösung scheint ordentlich – Gubr

+0

Ich erhalte einen Fehler: 'WaitAsync' ist kein Mitglied von 'System.Threading.SemaphoreSlim' – carlot0820

+0

das ist so tief! Tut mir leid, ich bin ein Neuling. – carlot0820

0

Ich konnte bekommen, was ich will mit einem BackgroudWorker. Ich legte die SpeakAsync Code an die BackgroudWorker und ersetzt die

SpeechSynthesizer.SpeakAsync("Ticket number " & TTSTicket & ", please proceed to counter " & TTSCounter)

mit

 If SpeechBackgroundWorker.IsBusy = False Then 

     TTSCounter = CRichTextBox.Text 
     TTSTicket = TRichTextBox.Text 

     SpeechBackgroundWorker.RunWorkerAsync() 

     Exit Sub 

     End If 

Es reiht erfolgreich die Reden und es nicht den UI-Thread beeinflussen. Hoffe das hilft!

Verwandte Themen