Angenommen, ich besitze eine Bibliothek für nicht auf UI basierende Anwendungen (ASP.NET) und auf UI-basierte Anwendungen (WinForm und WPF). Leider kann ich nicht vermeiden, IO-gebundene Arbeit und CPU-gebundene Arbeit zu mischen, aber ich lasse die Verbraucher DummyWorkAsync
über Task.Run
aufrufen oder nicht basierend auf ihren Anwendungstypen (Nicht-UI- oder UI-basierte Anwendungen).Gibt es einen Unterschied zwischen normalem Lambda und asynchronem Lambda?
class DummyService
{
public static async Task<int> DummyWorkAsync()
{
// Do some I/O first.
await Task.Delay(1000);
// Tons of work to do in here!
for (int i = 0; i != 10000000; ++i)
;
// Possibly some more I/O here.
await Task.Delay(1000);
// More work.
for (int i = 0; i != 10000000; ++i)
;
return 0;
}
}
Dies ermöglicht UI-basierte Verbraucher richtig Task.Run
zu verwenden, um den Dienst zu nennen, während ASP.NET-Clients nur die Methode direkt wie folgt nennen würde.
private async void MyButton_Click(object sender, EventArgs e)
{
await Task.Run(() => DummyService.DummyWorkAsync());
}
public class Home: Controller
{
public async Task<ActionResult> IndexAsync()
{
var result = await DummyService.DummyWorkAsync();
return View(result);
}
}
Frage
ich in den UI-basierten Anwendungen interessiert. Gibt es einen Unterschied, ob ich
private async void MyButton_Click(object sender, EventArgs e)
{
await Task.Run(async() => await DummyService.DummyWorkAsync());
}
statt
private async void MyButton_Click(object sender, EventArgs e)
{
await Task.Run(() => DummyService.DummyWorkAsync());
}
verwenden?
Der erste wäre nur nützlich, wenn Sie etwas nach dem Beenden von 'DummyWorkAsync' im UI-Thread tun müssen. Technisch gesehen wartet es eigentlich darauf, dass es fertig ist, aber den UI-Thread zwischenzeitlich nicht blockiert. – juharr
@Clemens: Weil es im "hybriden" 'DummyWorkAsync' einige CPU-gebundene Werke gibt. Wir müssen 'Task.Run' in UI-basierten Apps für eine solche hybride asynchrone Methode verwenden. –
Da Ihr IO zuerst geht (ich meine, warten Sie zuerst auf Task.Delay), warum fügen Sie nicht einfach ConfigureAwait (false) hinzu? Dann können Sie es auch von der Benutzeroberfläche aufrufen, ohne in Task.Run zu verpacken. – Evk