Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Threading: Oberflächenverarbeitung von Logikcode-Verarbeitung trennen
Maddinel
myCSharp.de - Member

Avatar #avatar-3180.gif


Dabei seit:
Beiträge: 1.371
Herkunft: Deutschland

Themenstarter:

Threading: Oberflächenverarbeitung von Logikcode-Verarbeitung trennen

beantworten | zitieren | melden

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!!!
==============================
private Nachricht | Beiträge des Benutzers
winSharp93
myCSharp.de - Experte

Avatar #avatar-2918.png


Dabei seit:
Beiträge: 5.742
Herkunft: Stuttgart

beantworten | zitieren | melden

Hallo Maddinel,

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

Geht es mit dem ThreadPool bzw. einem Task?
private Nachricht | Beiträge des Benutzers
Maddinel
myCSharp.de - Member

Avatar #avatar-3180.gif


Dabei seit:
Beiträge: 1.371
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

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!!!
==============================
private Nachricht | Beiträge des Benutzers
winSharp93
myCSharp.de - Experte

Avatar #avatar-2918.png


Dabei seit:
Beiträge: 5.742
Herkunft: Stuttgart

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Maddinel
myCSharp.de - Member

Avatar #avatar-3180.gif


Dabei seit:
Beiträge: 1.371
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

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?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Maddinel am .
==============================
Wenn ichs wüsst', würd' ich nicht fragen!!!
==============================
private Nachricht | Beiträge des Benutzers
winSharp93
myCSharp.de - Experte

Avatar #avatar-2918.png


Dabei seit:
Beiträge: 5.742
Herkunft: Stuttgart

beantworten | zitieren | melden

Zitat von Maddinel
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.
private Nachricht | Beiträge des Benutzers
Maddinel
myCSharp.de - Member

Avatar #avatar-3180.gif


Dabei seit:
Beiträge: 1.371
Herkunft: Deutschland

Themenstarter:

beantworten | zitieren | melden

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!!!
==============================
private Nachricht | Beiträge des Benutzers