Hallo,
ich habe hier ein kurzes Minimalbeispiel zur Verwendung von Async/Await innerhalb einer GUI, siehe Code:
Dieser Implementierung sind vielleicht einige Ideen zu entnehmen. Ich habe zunächst einen Button2, mit dem ich den Code und den Zugriff auf das GUI Element (Listbox) synchron bewerkstellige. Soweit so gut, verursacht dies das bekannte "einfrieren" der Form. Zur Vermeidung des Einfrierens wurde der quasi gleiche Code in eine neue Methode PutData() ausgelagert, bei der Mittels Invoke auch von einem anderen Thread aus Zugriff auf das GUI Element erlaubt wird. Jetzt gibt es noch weitere Button Implementierungen. Zum einen den "asynchronen"-Button1, der die Methode PutData() aufruft, außerdem den Button3, der den asynchronen Code über eine CallerMethode aufruft, so erspare ich mir den "asynchronen" Button.
Jetzt gibt es hier verschieden philosophische Ansätze, bsp. könnte man auch, wie der @ErfinderDesRades oft vorschlägt auch die "Dateneingabe" auslagern. Also erst Daten sammeln und dann zurück (z.B. synchron) in die GUI einspeisen. Meine Frage bzw. Fragen, richten sich nach der "perfekten" Implementierung und Verwendung von Async und Await. Wenn Ihr diese unterschiedlichen Ansätze seht, welcher davon wäre der idealste? Ist es überhaupt notwendig/sinnvoll einen Button nicht asynchron zu gestalten. Ich habe im Netzt verschiedene Implementierungen von Async/Await gesehen, häufig lassen sich diese jedoch auf zwei Formen reduzieren, entweder direkt den asynchronen Teil im Button (vergleiche hierzu die Implementierung in Button1) verwenden, oder es wird eine Hilfsmetode zu Rate gezogen, die dann den asynchronen Teil ausführt. Mich interessieren eure Meinungen.
ich habe hier ein kurzes Minimalbeispiel zur Verwendung von Async/Await innerhalb einer GUI, siehe Code:
C#-Quellcode
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- namespace LoadDataInGUI
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
- private async void Button1_ClickAsync(object sender, EventArgs e)
- {
- await Task.Run(() => PutData());
- }
- // Caller method to avoid async button
- private async void CallerMethod()
- {
- await Task.Run(() => PutData());
- }
- private void PutData()
- {
- // Load data from file
- string[] data = File.ReadAllLines(@"C:\...\4000Lines.txt");
- // Put data into GUI
- foreach (string line in data)
- {
- listBox1.Invoke(new Action(() => listBox1.Items.Add(line)));
- }
- }
- private void Button2_Click(object sender, EventArgs e)
- {
- // Load data from file
- string[] data = File.ReadAllLines(@"C:\...\4000Lines.txt");
- // Put data into GUI
- foreach (string line in data)
- {
- listBox1.Items.Add(line);
- }
- }
- private void Button3_Click_1(object sender, EventArgs e)
- {
- CallerMethod();
- }
- }
- }
Dieser Implementierung sind vielleicht einige Ideen zu entnehmen. Ich habe zunächst einen Button2, mit dem ich den Code und den Zugriff auf das GUI Element (Listbox) synchron bewerkstellige. Soweit so gut, verursacht dies das bekannte "einfrieren" der Form. Zur Vermeidung des Einfrierens wurde der quasi gleiche Code in eine neue Methode PutData() ausgelagert, bei der Mittels Invoke auch von einem anderen Thread aus Zugriff auf das GUI Element erlaubt wird. Jetzt gibt es noch weitere Button Implementierungen. Zum einen den "asynchronen"-Button1, der die Methode PutData() aufruft, außerdem den Button3, der den asynchronen Code über eine CallerMethode aufruft, so erspare ich mir den "asynchronen" Button.
Jetzt gibt es hier verschieden philosophische Ansätze, bsp. könnte man auch, wie der @ErfinderDesRades oft vorschlägt auch die "Dateneingabe" auslagern. Also erst Daten sammeln und dann zurück (z.B. synchron) in die GUI einspeisen. Meine Frage bzw. Fragen, richten sich nach der "perfekten" Implementierung und Verwendung von Async und Await. Wenn Ihr diese unterschiedlichen Ansätze seht, welcher davon wäre der idealste? Ist es überhaupt notwendig/sinnvoll einen Button nicht asynchron zu gestalten. Ich habe im Netzt verschiedene Implementierungen von Async/Await gesehen, häufig lassen sich diese jedoch auf zwei Formen reduzieren, entweder direkt den asynchronen Teil im Button (vergleiche hierzu die Implementierung in Button1) verwenden, oder es wird eine Hilfsmetode zu Rate gezogen, die dann den asynchronen Teil ausführt. Mich interessieren eure Meinungen.