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

Mit Task.Wait() auf einen Task warten, der nicht mit Task.Run() gestartet wurde
tkrasinger
myCSharp.de - Member



Dabei seit:
Beiträge: 582
Herkunft: Enzesfeld (Niederösterreich)

Themenstarter:

Mit Task.Wait() auf einen Task warten, der nicht mit Task.Run() gestartet wurde

beantworten | zitieren | melden

private void Button_Click(object sender, RoutedEventArgs e)
{
    //Variante a) not working:
    Task t = CreateTestFile();
    t.Wait();

    //Variante b) working:
    Task t2 = Task.Run( () => CreateTestFile());
    t2.Wait();
}

private async Task CreateTestFile()
{
    IStorageFolder rootPath;
    if (!(await FolderExists(ApplicationData.Current.LocalFolder, "Test")))
    {
        rootPath = await ApplicationData.Current.LocalFolder.CreateFolderAsync("Test");
    }
    else
    {
        rootPath = await ApplicationData.Current.LocalFolder.GetFolderAsync("Test");
    }
    var file1 = await rootPath.CreateFileAsync(DateTime.Now.ToString("HHmm") + ".txt");
    return;
}

public async Task<bool> FolderExists(IStorageFolder rootPath, string foldername)
{
    try
    {
        await rootPath.GetFolderAsync(foldername);
        return true;
    }
    catch
    {
        return false;
    }
}

Wenn ich den Button klicke und den unteren Code aufrufe mit Task.Run() dann funktioniert das einwandfrei und relativ flott.
Wenn ich es allerdings mit Task.Wait() ausführe, dann passiert irgendwie gar nichts, der Code bleibt irgendwo hängen. Wenn ich dann probiere langsam durchzudebuggen, läuft auch der Code durch ...

Was mache ich falsch bzw. wo liegt der Unterschied?
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15510
Herkunft: BW

beantworten | zitieren | melden

Am korrektesten wäre eigentlich



private async void Button_Click(object sender, RoutedEventArgs e)
{
   String testFile = await CreateTestFile();
}


private async Task<String> CreateTestFile()
 {
     IStorageFolder rootPath;
     if (!(await FolderExists(ApplicationData.Current.LocalFolder, "Test")))
     {
         rootPath = await ApplicationData.Current.LocalFolder.CreateFolderAsync("Test");
     }
     else
     {
         rootPath = await ApplicationData.Current.LocalFolder.GetFolderAsync("Test");
     }

     var testFile = DateTime.Now.ToString("HHmm") + ".txt";

     var file1 = await rootPath.CreateFileAsync(testFile);

     return testFile ;
 }
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo tkrasinger,

eine Task wird nicht durch das reine Erstellen gestartet, sondern erst durch den Aufruf von Run*. Entsprechend macht Wait es auch nur Sinn, wenn die Task vorher mit Run gestartet wurde. Sonst wird endlos gewartet. Mit Task.Wait kann man natürlich nichts ausführen, sondern nur auf die Ausführung warten**.

Allerdings macht Run und Wait direkt hintereinander normalerweise keinen Sinn, weil der Code dann zwar in einem anderen Thread läuft, aber der aufrufende Thread solange blockiert ist, wie der Code läuft und damit (ziemlich) genauso lange, als wenn er den Code selbst ausgeführt hätte. Gerade wenn der aufrufende Thread wie in deinem Beispiel offensichtlich der GUI-Thread ist, ist das unsinnig, siehe [FAQ] Warum blockiert mein GUI?, Abschnitt "Noch eine Falle".

Wenn man - wie von Abt vorgeschlagen - await verwendet, teil der Compiler den Code der Methode so auf, dass der aufrufende Thread nicht blockiert wird.

* es gibt zwar noch andere Wege eine Task zu starten außer Run, aber die Erzeugung alleine reicht eben nicht

** Wait führt zwar nicht zwangsläufig zu einer Blockierung des aktuellen Threads, da der aktuelle Thread, sofern möglich, die Task, auf die per Wait "gewartet" wird, ausführen kann, aber das ändert nichts daran, dass der Thread nichts anderes tun kann, bis die Task fertig ist.

herbivore
private Nachricht | Beiträge des Benutzers