Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><code>Task.Yield()</code> is great for "punching a hole" in an otherwise synchronous part of an <code>async</code> method.</p> <p>Personally I've found it useful in cases where I have a self-cancelling <code>async</code> method (one which manages its own corresponding <code>CancellationTokenSource</code> and cancels the previously created instance on each subsequent call) that can be called multiple times within an extremely short time period (i.e. by interdependent UI elements' event handlers). In such a situation using <code>Task.Yield()</code> followed by an <code>IsCancellationRequested</code> check as soon as the <code>CancellationTokenSource</code> is swapped out can prevent doing potentially expensive work whose results will end up discarded anyway.</p> <p>Here's an example where only the last queued call to SelfCancellingAsync gets to perform expensive work and run to completion.</p> <pre><code>using System; using System.Threading; using System.Threading.Tasks; namespace TaskYieldExample { class Program { private static CancellationTokenSource CancellationTokenSource; static void Main(string[] args) { SelfCancellingAsync(); SelfCancellingAsync(); SelfCancellingAsync(); Console.ReadLine(); } private static async void SelfCancellingAsync() { Console.WriteLine("SelfCancellingAsync starting."); var cts = new CancellationTokenSource(); var oldCts = Interlocked.Exchange(ref CancellationTokenSource, cts); if (oldCts != null) { oldCts.Cancel(); } // Allow quick cancellation. await Task.Yield(); if (cts.IsCancellationRequested) { return; } // Do the "meaty" work. Console.WriteLine("Performing intensive work."); var answer = await Task .Delay(TimeSpan.FromSeconds(1)) .ContinueWith(_ =&gt; 42, TaskContinuationOptions.ExecuteSynchronously); if (cts.IsCancellationRequested) { return; } // Do something with the result. Console.WriteLine("SelfCancellingAsync completed. Answer: {0}.", answer); } } } </code></pre> <p>The goal here is to allow the code which executes synchronously on the same <code>SynchronizationContext</code> immediately after the non-awaited call to the async method returns (when it hits its first <code>await</code>) to change the state that affects the execution of the async method. This is throttling much like that achieved by <code>Task.Delay</code> (i'm talking about a non-zero delay period here), but without the <em>actual</em>, potentially noticeable delay, which can be unwelcome in some situations.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload