Advertisement
Noseratio

SO-19613444

Oct 27th, 2013
425
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.52 KB | None | 0 0
  1. // http://stackoverflow.com/a/19616899/1768303
  2. // http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx
  3.  
  4. // We want:
  5. /*
  6. Before pause requested
  7. Before await pause.WaitWhilePausedAsync()
  8. After pause requested.
  9. After await pause.WaitWhilePausedAsync()
  10. */
  11.  
  12. // We have:
  13. /*
  14. Before pause requested
  15. After pause requested.
  16. Before await pause.WaitWhilePausedAsync()
  17. After await pause.WaitWhilePausedAsync()
  18. */
  19.  
  20.  
  21. using System;
  22. using System.Collections.Generic;
  23. using System.Linq;
  24. using System.Text;
  25. using System.Threading;
  26. using System.Threading.Tasks;
  27.  
  28. namespace ConsoleApplication
  29. {
  30.     class Program
  31.     {
  32.         public class PauseTokenSource
  33.         {
  34.             private volatile TaskCompletionSource<bool> m_paused;
  35.  
  36.             public bool IsPaused
  37.             {
  38.                 get { return m_paused != null; }
  39.                 set
  40.                 {
  41.                     if (value)
  42.                     {
  43.                         Interlocked.CompareExchange(
  44.                             ref m_paused, new TaskCompletionSource<bool>(), null);
  45.                     }
  46.                     else
  47.                     {
  48.                         while (true)
  49.                         {
  50.                             var tcs = m_paused;
  51.                             if (tcs == null) return;
  52.                             if (Interlocked.CompareExchange(ref m_paused, null, tcs) == tcs)
  53.                             {
  54.                                 tcs.SetResult(true);
  55.                                 break;
  56.                             }
  57.                         }
  58.                     }
  59.                 }
  60.             }
  61.  
  62.             internal Task WaitWhilePausedAsync()
  63.             {
  64.                 var cur = m_paused;
  65.                 return cur != null ? cur.Task : s_completedTask;
  66.             }
  67.  
  68.             internal static readonly Task s_completedTask = Task.FromResult(true);
  69.  
  70.             public PauseToken Token { get { return new PauseToken(this); } }
  71.         }
  72.  
  73.         public struct PauseToken
  74.         {
  75.             private readonly PauseTokenSource m_source;
  76.             internal PauseToken(PauseTokenSource source) { m_source = source; }
  77.  
  78.             public bool IsPaused { get { return m_source != null && m_source.IsPaused; } }
  79.  
  80.             public Task WaitWhilePausedAsync()
  81.             {
  82.                 return IsPaused ?
  83.                     m_source.WaitWhilePausedAsync() :
  84.                     PauseTokenSource.s_completedTask;
  85.             }
  86.         }
  87.  
  88.         static void Main()
  89.         {
  90.             var pts = new PauseTokenSource();
  91.             var task = SomeMethodAsync(pts.Token);
  92.             Task.Run(() =>
  93.             {
  94.                 Console.WriteLine("Before pause requested");
  95.                 pts.IsPaused = true;
  96.                 Console.WriteLine("After pause requested.");
  97.                 pts.IsPaused = false;
  98.                 Console.ReadLine();
  99.             }).Wait();
  100.             Console.ReadLine();
  101.         }
  102.  
  103.         public static async Task SomeMethodAsync(PauseToken pause)
  104.         {
  105.             await Task.Delay(500);
  106.             Console.WriteLine("Before await pause.WaitWhilePausedAsync()");
  107.             await pause.WaitWhilePausedAsync();
  108.             Console.WriteLine("After await pause.WaitWhilePausedAsync()");
  109.         }
  110.     }
  111. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement