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
Einfrieren des GUIs verhindern: Thread oder Backgroundworker für asynchrone Vorgänge?
reloop
myCSharp.de - Member

Avatar #avatar-3256.jpg


Dabei seit:
Beiträge: 139

Themenstarter:

Einfrieren des GUIs verhindern: Thread oder Backgroundworker für asynchrone Vorgänge?

beantworten | zitieren | melden

Hallo liebe Community,

ich habe eine Frage zum Umgang der beiden o.g. Objekte. Ich möchte in einer Combobox suchen, welche an eine List<> gebunden ist. Da die Anwendung immer kurz hängt, wenn sich das DropDown mit den neuen Daten öffnet, möchte ich dieesen Vorgang gerne auslagern.

Nun meine Frage:

Nutze ich dafür einen Thread im ComboBox-DropdownOpen Event?

Und wie löse ich das Problem, wenn ich NACH beenden des Threads noch Code ausführen will? Quasi einen "ExitCode" oder "DoAfterWorkCode".

Oder ist mein Ansatz komplett Falsch und ich sollte auf einen Backgroundworker zurückgreifen?

Gruss,
reloop
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 6.856
Herkunft: Waidring

beantworten | zitieren | melden

Hallo,

grundsätzlich startest du im Ereignis-Handler einen asynchronen Vorgang - damit die UI nicht einfriert - und wenn in diesem Vorgang das Ergebnis vorliegt aktualisiert du die UI wie in [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke) beschrieben.


mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
reloop
myCSharp.de - Member

Avatar #avatar-3256.jpg


Dabei seit:
Beiträge: 139

Themenstarter:

beantworten | zitieren | melden

Danke gfoidl.

Also kurzgefasst ist mein Vorgang dieser:

ComboboxOpen
---Thread der die Funktion "ManageMySearch" Aufruft
-----"ManageMySearch" beinhaltet die Filterung der Liste + einen AsyncCallBack mit der aktualisierung der Gui?

Gruss und vielen Dank,
reloop
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 6.856
Herkunft: Waidring

beantworten | zitieren | melden

Hallo,

das AsyncCallBack brauchst du nicht.

Cica so:


private void ComboboxOpen(object sender, EventArgs e)
{
    ThreadPool.QueueUserWorktItem(_ =>
    {
        IEnumerable<string> results = MyFilterMethod(...);

        Action<IEnumerable<string>> cheapUIAccess = r => myListBox.DataSource = r;

        this.BeginInvoke(cheapUIAccess, results);
    });
}



mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
reloop
myCSharp.de - Member

Avatar #avatar-3256.jpg


Dabei seit:
Beiträge: 139

Themenstarter:

beantworten | zitieren | melden

Umgebaut auf meine Anwendung sieht es jetzt so aus:

             ThreadPool.QueueUserWorkItem(_ =>
            {
                var searchResult = ReturnSearchResult(_search);

                Action<List<myData>> cheapUIAccess = r => ItemsSource = r;

                Dispatcher.BeginInvoke(cheapUIAccess, searchResult);
            });  


Verstehe ich den Ablauf richtig? der QueueUserWorkItem hängt die ihm über Lambda zugewiesene Methode dem Pool an abzuarbeitenden Methoden an?

Und wird mit Action<List<myData>> cheapUIAcess eine Methode erstellt, mit dem Parameter "r", der in der Methode selbst den ItemsSource mit seinem wert belegt?

Und zum Schluss wird mithilfe des BeginInvoke diese Funktion aufgerufen (cheapUiAcess) und der Parameter "searchResult" stellt indem Fall mein "r" da?

Verzeih mir diese Laienhaften Fragen, aber das hilft es mir besser zu verstehen.

Und eine Frage zum Schluss: Wo ist der Vorteil des QueueUserWorkItem gegenüber einem eigenen Thread? Oder wird er dadurch erzeugt?

Danke für deine Hilfe,
deine Beiträge sind mir jedes eine riesen Hilfe.

Gruss,
reloop

PS: Funktionieren tut es spitze!
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von reloop am .
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 6.856
Herkunft: Waidring

beantworten | zitieren | melden

Hallo,

zu den Frage: 3x Ja

Der ThreadPool hat den Vorteil dass dort Threads auf Lager sind -> einer wird genommen für die Arbeit und dann wieder auf das Lager gelegt. Das ist vorteilhaft im Vergleich zu jedesmal einen Thread erstellen, diesen arbeiten lassen und dann zerstören - da die Threaderstellung aufwändig ist.

Wenn du .net 4.0 verwendest wäre der zu bevorzugende Weg der über Tasks. Diese stellen eine weitere Abstraktion der Arbeit mit Threads dar (und intern wird standardmäßig mit dem ThreadPool - aus oben genannten Gründen - gearbeitet). Hier gibt es zusätzlich die Möglichkeit oder den Vorteil eines speziellen TaskSchedulers zu verwenden die es erlaubt ohne expliziten Invoke/BeginInvoke auf die UI zuzugreifen. Der Code wäre dann wie folgt (reduziert):


Task.Factory.StartNew(
	delegateForWork,
	CancellationToken.None,		// oder wenn du es abbrechen willst halt anderer Wert
	TaskCreationOptions.None,
	TaskScheduler.FromCurrentSynchronizationContext());
Somit "fangt" der TaskScheduler den aktuellen SynchronizationContext und dieser eledigt das delegieren in den UI-Thread.


mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
TheBrainiac
myCSharp.de - Member

Avatar #avatar-3152.png


Dabei seit:
Beiträge: 795
Herkunft: /dev/null

beantworten | zitieren | melden

Zitat von reloop
Wo ist der Vorteil des QueueUserWorkItem gegenüber einem eigenen Thread? Oder wird er dadurch erzeugt?

Es benutzt einen Thread aus dem Threadpool. Diese sind schon vorhanden und müssen nicht neu erzeut werden.

//Edit: zu spät :D
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von TheBrainiac am .
There are 10 types of people in the world:
Those, who think they understand the binary system
Those who don't even have heard about it
And those who understand "Every base is base 10"
private Nachricht | Beiträge des Benutzers
reloop
myCSharp.de - Member

Avatar #avatar-3256.jpg


Dabei seit:
Beiträge: 139

Themenstarter:

beantworten | zitieren | melden

Danke, habe es jetzt so umgesetzt wie o.g. und es ist genau das wonach ich gesucht habe.

Letzte Frage:

" ThreadPool.QueueUserWorkItem(_ =>" wofür steht in dem Fall das "_" ?

Bei MouseOver zeigt er mir an: "parameter (object) _" .. kann ich in dem Zusammenhang aber leider nicht wirklich in Verbindung bringen.
private Nachricht | Beiträge des Benutzers
aequitas
myCSharp.de - Member

Avatar #avatar-3079.png


Dabei seit:
Beiträge: 458
Herkunft: Unterfranken

beantworten | zitieren | melden

Das ist eine Lambda Expression.. man sollte normalerweise schon wissen was man tut und nicht einfach abtippen ;)
be the hammer, not the nail!
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 6.856
Herkunft: Waidring

beantworten | zitieren | melden

Hallo,

es ist ein das Argument des Delegaten für eine anonyme Methode, könnte auch jedes andere Zeichen sein oder sonst ein Argumentname. _ wird halt gewählt wenn dir sonst nix einfällt ;-)
Siehe auch [Artikel] Delegaten, anonyme Methoden, Lambda-Ausdrücke & Co.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers