Laden...

Threading: Oberflächenverarbeitung von Logikcode-Verarbeitung trennen

Erstellt von Maddinel vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.531 Views
Maddinel Themenstarter:in
1.371 Beiträge seit 2004
vor 12 Jahren
Threading: Oberflächenverarbeitung von Logikcode-Verarbeitung trennen

Hallo,

In meiner WPF-Anwendung habe ich ein UserControl erstellt, in dem u.a. über ein SoundPlayer-Objekt ein Wave-Sound abgespielt werden kann. In meinem speziellen Fall kann es vokommen, dass das das Abspielen des Sounds mehrmals hintereinander initiiert werden muss. Dies geschiet nicht über das Control direkt, sondern über eine Methode, die vom ParentWindow aus aufgerufen wird.

Ich ordne in meinem Layout mehrere dieser UserControls in einem StackPanel an. Der aufruf der Soundabspielenden Methode geschiet im MainWindow bereits über einen BackgroundWorker, damit mir verarbeitungstechnisch nicht dazwischen kommt. Das funktioniert an sich auch wunderbar. Wenn ich jetzt aber mein Fenster bzw. im StackPanel scrollen muss (über einen ScrollViewer), dann wird das eigentlich ja in den BackgroundWorker ausgelagerte Soundabspielen unterbrochen. Nach dem Scrollen geht es aber wieder direkt weiter.

Wie kann ich die Verarbeitung der Oberfläche von der restlichen Codeausführung so trennen, dass keine Unterbrechungen entstehen?

==============================
Wenn ichs wüsst', würd' ich nicht fragen!!! 😁
==============================

5.742 Beiträge seit 2007
vor 12 Jahren

Hallo Maddinel,

dann hast du wahrscheinlich falsch in einen Thread ausgelagert - zeige mal etwas Code.

Geht es mit dem ThreadPool bzw. einem Task?

Maddinel Themenstarter:in
1.371 Beiträge seit 2004
vor 12 Jahren

Ich hab definitiv falsch ausgelagert. Ich gehe so vor (sorry, dass ich keinen realen Code poste, aber das wäre auf die Schnelle zu unübersichtlich):


BackgroundWorker bw;
Timer timer;

private void timer_Tick(...)
{
    bw.RunWorkerAsync();
}

private void bw_DoWork(...)
{
    foreach(MyUserControl myControl in (MyUserControl)StackPanel.Children)
    {
        myControl.DoSomethingWithSound();
    }
}

Mir ist jetzt natürlich auch klar, dass lediglich der einzelne Methodenaufruf meiner UserControls in einem separaten Thread durchgeführt wird, allerdings läuft der Timer an sich ja im MainThread. Genau das ist wahrscheinlich hier auch das Problem. Die Timerausführung kann behindert erden, wenn ich die Oberfläche scrolle. Wie könnte ich aber auch die Timerausführung auslagern?

==============================
Wenn ichs wüsst', würd' ich nicht fragen!!! 😁
==============================

5.742 Beiträge seit 2007
vor 12 Jahren

Du darfst nur aus dem GUI Thread auf Controls zugreifen - das gilt sowohl für WinForms als auch für WPF - siehe [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke)

Dass deine Controls eine blockierende DoSomethingWithSound Methode bereitstellen ist somit ein Designfehler.

Maddinel Themenstarter:in
1.371 Beiträge seit 2004
vor 12 Jahren

Das ist eigentlich gar nicht swo sehr das Problem. Die Methode ist im Prinzip nicht blockierend. Ich hatte den Methodenaufruf eigentlich nur aus Verzweiflung in den BackgroundWorker ausgelagert. Mein Hauptproblem ist eigentlich, dass der Timerdurchlauf durch die Oberflächenbehandlung (scrolling) behindert wird. Wie könnte ich das verbessern?

==============================
Wenn ichs wüsst', würd' ich nicht fragen!!! 😁
==============================

5.742 Beiträge seit 2007
vor 12 Jahren

dass der Timerdurchlauf durch die Oberflächenbehandlung (scrolling) behindert wird.

Nochmal: Auch ein Timer ist bereits ein zweiter Thread, aus dem GUI Zugriffe synchronisiert werden müssen.

Evtl. löst ein DispatcherTimer dein Problem.

Maddinel Themenstarter:in
1.371 Beiträge seit 2004
vor 12 Jahren

Hmm dann muss ich wohl noch ein wenig suchen und ausprobieren. Ich dank dir erst mal für die Tipps.

==============================
Wenn ichs wüsst', würd' ich nicht fragen!!! 😁
==============================