Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // http://stackoverflow.com/a/19616899/1768303
- // http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx
- // We want:
- /*
- Before pause requested
- Before await pause.WaitWhilePausedAsync()
- After pause requested.
- After await pause.WaitWhilePausedAsync()
- */
- // We have:
- /*
- Before pause requested
- After pause requested.
- Before await pause.WaitWhilePausedAsync()
- After await pause.WaitWhilePausedAsync()
- */
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- namespace ConsoleApplication
- {
- class Program
- {
- public class PauseTokenSource
- {
- private volatile TaskCompletionSource<bool> m_paused;
- public bool IsPaused
- {
- get { return m_paused != null; }
- set
- {
- if (value)
- {
- Interlocked.CompareExchange(
- ref m_paused, new TaskCompletionSource<bool>(), null);
- }
- else
- {
- while (true)
- {
- var tcs = m_paused;
- if (tcs == null) return;
- if (Interlocked.CompareExchange(ref m_paused, null, tcs) == tcs)
- {
- tcs.SetResult(true);
- break;
- }
- }
- }
- }
- }
- internal Task WaitWhilePausedAsync()
- {
- var cur = m_paused;
- return cur != null ? cur.Task : s_completedTask;
- }
- internal static readonly Task s_completedTask = Task.FromResult(true);
- public PauseToken Token { get { return new PauseToken(this); } }
- }
- public struct PauseToken
- {
- private readonly PauseTokenSource m_source;
- internal PauseToken(PauseTokenSource source) { m_source = source; }
- public bool IsPaused { get { return m_source != null && m_source.IsPaused; } }
- public Task WaitWhilePausedAsync()
- {
- return IsPaused ?
- m_source.WaitWhilePausedAsync() :
- PauseTokenSource.s_completedTask;
- }
- }
- static void Main()
- {
- var pts = new PauseTokenSource();
- var task = SomeMethodAsync(pts.Token);
- Task.Run(() =>
- {
- Console.WriteLine("Before pause requested");
- pts.IsPaused = true;
- Console.WriteLine("After pause requested.");
- pts.IsPaused = false;
- Console.ReadLine();
- }).Wait();
- Console.ReadLine();
- }
- public static async Task SomeMethodAsync(PauseToken pause)
- {
- await Task.Delay(500);
- Console.WriteLine("Before await pause.WaitWhilePausedAsync()");
- await pause.WaitWhilePausedAsync();
- Console.WriteLine("After await pause.WaitWhilePausedAsync()");
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement