Wachten op asynchrone/wachten binnen een taak

Ik heb deze constructie in mijn main(), die

. creëert

var tasks = new List<Task>();
var t = Task.Factory.StartNew(
    async () =>
    {
        Foo.Fim();
        await Foo.DoBar();
    });
//DoBar not completed
t.Wait();
//Foo.Fim() done, Foo.DoBar should be but isn't

Als ik echter .Waitop t, wacht het niet tot de aanroep van DoBar()is voltooid.
Hoe zorg ik ervoor dat het echt wacht?


Antwoord 1, autoriteit 100%

Het wordt afgeraden om Task.Factory.StartNewte gebruiken met async-await, in plaats daarvan zou u Task.Runmoeten gebruiken:

var t = Task.Run(
    async () =>
    {
        Foo.Fim();
        await Foo.DoBar();
    });

De api Task.Factory.StartNewis gebouwd vóór de Taakgebaseerd asynchroon patroon (TAP)en async-await. Het retourneert Task<Task>omdat je een taak start met een lambda-expressie die toevallig async is en dus een taak retourneert. Unwrapzal de innerlijke taak extraheren, maar Task.Runzal dat impliciet voor je doen.


Voor een diepere vergelijking is er altijd een relevant Stephen Toub-artikel: Task.Run vs Task.Factory.StartNew


Antwoord 2, autoriteit 6%

Het lijkt erop dat ik de gewenste functionaliteit krijg door Unwrap()de taak uit te voeren.
Ik weet niet zeker of ik de redenering hierachter begrijp, maar ik veronderstel dat het werkt.

var t = Task.Factory.StartNew(
            async () =>
                {
                        Foo.Fim();
                        await Foo.DoBar();
                }).Unwrap();

edit: ik heb gezocht naar ddescription van Unwrap():
Creates a proxy Task that represents the asynchronous operation of a Task<Task<T>>vertegenwoordigt
Ik dacht dat dit traditioneel was wat de taak deed, maar als ik uitpakken moet bellen, denk ik dat dat prima is.


Antwoord 3

Ik had onlangs een soortgelijk probleem en kwam erachter dat je alleen maar DoBar()een waarde hoeft te retourneren en .Result te gebruiken in plaats van te wachten.

var g = Task.Run(() => func(arg));
var val = g.Result;

Dit zal wachten tot funczijn output retourneert en toewijst aan val.

Other episodes