myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns
» Datenschutzerklärung
» Impressum

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Grundlagen von C# » Wie kann man Code wirklich asynchron aufrufen?
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Wie kann man Code wirklich asynchron aufrufen?

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
cRUSHERHLG
myCSharp.de-Mitglied

Dabei seit: 25.06.2018
Beiträge: 27


cRUSHERHLG ist offline

Wie kann man Code wirklich asynchron aufrufen?

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich habe da grundsätzlich die Frage wie man Code wirklich asynchron aufrufen kann.

Im folgenden Code ist die Methodendefinition zwar mit async und Task<string> aber es wird durch das await wieder aufgehoben, sodass es als synchrone Methode ausgeführt wird. Der Grund für den inneren await ist nur wegen der Entfernung der Warnung.

C#-Code:
public static async Task<string> Uptime()
        {
            return await Task.Run(() =>
            {
                TimeSpan uptime = TimeSpan.FromMilliseconds(NativeMethods.Kernel32.GetTickCount64());

                string days = uptime.Days + " Days";
                string hours = uptime.Hours + " Hours";
                string minutes = uptime.Minutes + " Minutes";
                string seconds = uptime.Seconds + " Seconds";

                return days + ", " + hours + ", " + minutes + ", " + seconds;
            });
        }

Ich habe mir die Library von Abt (AsyncAll) angeschaut. Soll sie wirklich so funktionieren, das sie auch synchrone Methoden wie z.B. im Code oben dann asynchron ablaufen.
Ist diese noch aktuell sodass man sie noch nutzen kann, da der letzte commit vor über 3 Jahren her ist.

Habe mir zu dem Thema auch mehrere Artikel und Beitrage von Microsoft und co. durchgelesen.
Es ist nur verwirrend, da sich die Erklärungen öfters widersprechen von daher möchte ich fragen welche Quellen man eurerseits als vertrauenswürdig einzustufen sind.

Dazu dann noch ergänzend habt ihr vielleicht selbst Erfahrungen zu dem Thema oder auch Patterns die ihr empfiehlt.

MfG,
cRUSHER
07.06.2019 02:25 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.225
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Der Sinn von Abts Lib steckt im Namen und dort werden synchrone Methoden du durch z.B. Action oder andere definierbare Mittel der Sprache durch die TaskFactory.StartNew in einem Task gekapselt und asynchron ausgeführt.
Also genau das Gegenteil von dem was du schreibst.

In einem Beispiel ist das async vermutlich falsch.
Deine Methode sollte, wenn Sie selbst kein await verwendet, schlicht nur einen Task liefern.
Ich habe z.B. bei einem Projekt immer die sychrone Methode mit einer Methode die einfach nur per Task.Run() ein neuen Task liefert ohne async/await umgesetzt.

Somit kann ich auch beide Varianten nutzen, wenn dies den nötig ist.
Ein besserer Ansatz wäre für dich ggf. auch ein Blick in die .NET Sourcen per Reference Code.
In .NET gibt es selbst viele Klasse die sowohl eine synchrone als auch eine asynchrone Methode anbieten.

Es hat sich in den letzten Jahren in dem Bereich auch nicht viel geändert.
Async/Await sind nun mal Sprachkonstrukte mit einem fixen Konzept.
Wenn du diese verstanden hast, kannst du diese auch für dein Zwecke nutzen.

Anbei wären auch Beispiele für Wiedersprüche hilfreich.
Viel falsch kann man eigentlich nicht machen, wenn man es einmal verstanden hat.
Und bei den Beispielen die ich bisher gelesen habe gibt es eigentlich keinen großen Spielraum für falsche Nutzung.
Ansonsten sei auf die Doku verwiesen.

T-Virus
07.06.2019 09:09 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
cRUSHERHLG
myCSharp.de-Mitglied

Dabei seit: 25.06.2018
Beiträge: 27

Themenstarter Thema begonnen von cRUSHERHLG

cRUSHERHLG ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Mein Beispiel von oben wie du es schon gesagt hast ist richtig, das es so wie es aktuell ist synchron aufgerufen wird. Es ist sogar noch etwas blöder, da ein Task in einem Task dadurch erstellt wird. Ich wollte mit dem vorgehen nur die Warnung ausbügeln.

Der Grund warum Task.Run im inneren der Methode zu finden ist, da er mir sonst Warnung herausgibt. Kann man diese dann ignorieren?

Kann man die Lib von Abt noch nutzen oder bedarf es einem update da seit 3 Jahren kein neuer commit dazugekommen ist oder hat sich seitdem nichts geändert?

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von cRUSHERHLG am 07.06.2019 10:31.

07.06.2019 10:28 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 12.740
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Den Beispielcode hier asynchron zu machen, ist inhaltlich maximal unsinnig.

Asynchrone Codeausfürhung verwendet man, um Ressourcen zu schonen, die durch ein Blockieren "warten" müssen.
Das ist bei vor allem Fällen bei externer Kommunikation (API Abfragen, Datenbankabfragen, lange Laufzeitberechnugen..) der Fall - niemals bei solch einem simplen Code.

Wenn Du den Code an dieser Stelle unbedingt asynchron machen willst - was unsinnig ist - dann lass das async/await weg - das brauchst Du nicht hier.
Du wartest ja nirgends auf etwas Externes:

C#-Code:
public static Task<string> Uptime()
        {
            return Task.Run(() =>
            {
                TimeSpan uptime = TimeSpan.FromMilliseconds(NativeMethods.Kernel32.GetTickCount64());

                string days = uptime.Days + " Days";
                string hours = uptime.Hours + " Hours";
                string minutes = uptime.Minutes + " Minutes";
                string seconds = uptime.Seconds + " Seconds";

                return days + ", " + hours + ", " + minutes + ", " + seconds;
            });
        }

Zitat von cRUSHERHLG:
Ich habe mir die Library von Abt (AsyncAll) angeschaut. Soll sie wirklich so funktionieren, das sie auch synchrone Methoden wie z.B. im Code oben dann asynchron ablaufen.

Nein, soll sie nicht. Behaupte ich auch nirgends.

AsyncAll ist ein Wrapper, der genau das macht, was Du hier mit Task.Run() machst.
Ziel ist Kompatibilitäten herzustellen und Übergangslösungen von sync auf async zu schaffen.

zB unterstützt die Win32 API für Dateien bis heute keine einfache Schnittstelle für async/await.
AsyncAll ändert das auch nicht - Du kannst damit aber Problemlos Dein Software Design darauf vorbereiten.

Zitat von cRUSHERHLG:
Der Grund warum Task.Run im inneren der Methode zu finden ist, da er mir sonst Warnung herausgibt.

Keiner hier kann hellsehen, von welcher Warnung Du sprichst.

Aber es ist immer eine schlechte Idee "irgendwas zu basteln", statt die Ursache der Meldung zu bekämpfen.

Zitat von cRUSHERHLG:
Kann man die Lib von Abt noch nutzen oder bedarf es einem update da seit 3 Jahren kein neuer commit dazugekommen ist oder hat sich seitdem nichts geändert?

Es hat sich nichts geändert. Es gibt aber hier nach dem aktuellen Wissensstand kein Grund, wieso die Lib hier eingesetzt werden sollte - ist unsinnig und nicht Ziel der Lib.
07.06.2019 10:40 Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.225
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Dein Beispiel ist in diesem Fall falsch.
Damit eine Methode als async markiert werden kann, muss sie intern mindestens einmal await nutzen.
Dies kann aber nur funktionieren, wenn innerhalb der async Methode eben ein Methode aufgerufen wird, die einen Task liefert ohne async Markierung.

Sonst hast du ja das klassische Henne-Ei Problem.
Du willst eine async Methode verwenden ohne await intern zu nutzen.
Und genau dies kreidet dir die Warnung auch an.
Dies funktioniert aber aus dem Konzepten von async/await schon gar nicht.

Beispiele:
 https://www.dotnetperls.com/async

C#-Code:
public static async void Methode1Async()
{
    // Hier auf den Task von Methode2Async warten.
    await Methode2Async();
}

private static Task Methode2Async()
{
    return Task.Run(() =>
    {
        Methode2();
    });
}

private static void Methode2()
{
    // Hier wird Code ausgewührt der lange laufen kann.
}

T-Virus
07.06.2019 10:46 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
cRUSHERHLG
myCSharp.de-Mitglied

Dabei seit: 25.06.2018
Beiträge: 27

Themenstarter Thema begonnen von cRUSHERHLG

cRUSHERHLG ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das würde dann heißen, dass ich nach deinem Beispiel sozusagen 3 Implementierung für eine Methode machen müsste. Gibts da nicht auch noch andere Wege wie man es async schafft. Wie würde denn der Code aus der oberen Methode aussehen wenn man ihn nun "richtig" als async methode schreiben möchte?
07.06.2019 21:03 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.225
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Mein Beispiel zeigt nur wie die unterste Methode als sync und async genutzt werden kann.
Es würde auch reichen, wenn du nur eine async Methode willst, dass du eben nur die Methode2Async anlegst und dort dann eben die Verarbeitung umsetzt.

Wie gesagt, solltest du dir mal .NET Code anschauen, wie dort die async Methoden umgesetzt wurden.
Wenn deine Methode kein await nutzt, kannst du auch in der Methode kein async in der signatur verwenden.
Du musst dann eben stumpf wie bei meiner Methode2Async einfach einen Task liefern.
Alle Methoden darüber, können dann ein await auf Methode2Async machen und als async markiert werden.

T-Virus
07.06.2019 21:15 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 12.740
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von cRUSHERHLG:
Wie würde denn der Code aus der oberen Methode aussehen wenn man ihn nun "richtig" als async methode schreiben möchte?

"Richtig" brauchst Du kein async; Du hast dadurch eher Nachteile als Vorteile.
Es wird eine State Machine erzeugt, die Overhead kostet - und sie wird nicht benötigt.

Es macht nur Sinn, wenn Du es aus Designsicht "brauchst".
Dein Fall wird in den Microsoft-Recommendations unter "do not use async, when..." fallen.
07.06.2019 22:42 Beiträge des Benutzers | zu Buddylist hinzufügen
cRUSHERHLG
myCSharp.de-Mitglied

Dabei seit: 25.06.2018
Beiträge: 27

Themenstarter Thema begonnen von cRUSHERHLG

cRUSHERHLG ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Generell kann man also sagen, das man async/Tasks nur nutzen sollte, wenn es auch um das Thema I/0 geht wo man sicherstellen will, das man auf Resourcen zugreifen kann, ohne das sie blockiert werden voneinander.
11.06.2019 16:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.225
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Geht nicht nur um I/O Aufgaben, hatte Abt auch schon oben geschrieben.
Generell kann man Tasks dort verwenden, wo eben auf Resourcen gewartet werden müsste.
Dazu gehört zwar I/O Aufgaben aber auch z.B. auf HTTP Anfragen o.ä.
Ebem langläufige Prozesse die deine Verarbeitung blockieren würden.

Der Sinn ist ja diese asynchron laufen zu lassen, damit die UI weiterarbeiten kann und somit nicht einfriet.
Das ist leider bis heute in vielen Anwendungen immer noch ein großes Problem.
Und genau da setzt async/await eben an um dieses Problemm auf der Ebene der Programmiersprache zu lösen.

T-Virus
11.06.2019 17:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 12.740
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von T-Virus:
Dazu gehört zwar I/O Aufgaben aber auch z.B. auf HTTP Anfragen o.ä.

HTTP Anfragen sind I/O ;-)

Zitat von T-Virus:
Der Sinn ist ja diese asynchron laufen zu lassen, damit die UI weiterarbeiten kann und somit nicht einfriet.

async/await ist nicht gebunden an die UI.
Es geht grundlegend generell darum, dass eine Verarbeitung nicht blockiert wird. Ob das nun die Verarbeitung der UI ist oder die eines Webservers, die keine UI hat: spielt keine Rolle.
Es geht einfach nur um das Blockieren und das effizientere Nutzen von Ressourcen.

Eine simple synchronous Calculation dahingehend auszulagern, ist keine effiziente Anwendung von async/await.

cRUSHERHLG, auch gerne mal wieder für Dich den Hinweis auf die Doc:
 The Task asynchronous programming model in C#
Da sind die Basics.
11.06.2019 18:24 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum
Antwort erstellen


© Copyright 2003-2019 myCSharp.de-Team | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 24.06.2019 23:21