Hacker News new | past | comments | ask | show | jobs | submit login

Yield in C# is frequently used for the same reasons as in Rust, although implementation details between fine-grained C# Tasks and even finer grained Rust Futures aggregated into large Tasks differ quite a bit.

Synchronous part of an async method in C# will run "inline". This means that should there be a computationally expensive or blocking code, a caller will not be able to proceed even if it doesn't await it immediately. For example:

    var ptask = Primes.Calculate(n); // returns Task<ulong[]>
    // Do other things...right?
    // Why are we stuck calculating the primes then?
    Console.WriteLine("Started.");
In order for the .Calculate to be able to continue execution "elsewhere" in a free worker thread, it would have to yield.

If a caller does not control .Calculate, the most common (and, sadly, frequently abused) solution is to simply do

    var task = Task.Run(Primes.Calculate);
    // Do something else
    var text = string.Join(',', await task);
If a return signature of a delegate is also Task, the return type will be flattened - just a Task<T>, but nonetheless the returned task will be a proxy that will complete once the original task completes. This successfully deals with badly behaved code.

However, a better solution is to instead insert `Task.Yield()` to allow the caller to proceed and not be blocked, before continuing a long-running operation:

    var ptask = Primes.Calculate(n); // returns Task<ulong[]>
    // Successfully prints the message
    Console.WriteLine("Started.");


    static async Task<int[]> CalculatePrimes(int n)
    {
        await Task.Yield();
        // Continue execution in a free worker thread
        // If the caller immediately awaits us, most likely
        // the caller's thread will end up doing so, as the
        // continuation will be scheduled in the local queue,
        // so it is unlikely for the work item to be stolen this
        // quickly by another worker thread.
    }



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: