¿Un patrón para pausar / reanudar una tarea asíncrona?

Tengo una tarea continua mayoritariamente vinculada a IO (un corrector ortográfico de fondo que habla con un servidor de corrección ortográfica). A veces, esta tarea debe suspenderse y reanudarse más tarde, según la actividad del usuario.

Mientras que suspender / reanudar es esencialmente lo que hace async/await , he encontrado poca información sobre cómo implementar la lógica de pausa / reproducción real para un método asíncrono. ¿Hay un patrón recomendado para esto?

También he considerado usar AsyncManualResetEvent Stephen Toub para esto, pero pensé que podría ser una exageración.

AsyncManualResetEvent es exactamente lo que necesita, teniendo en cuenta lo desordenado que es su código actual. Pero una solución ligeramente mejor sería usar otro enfoque de Stephen Toub: PauseToken . Funciona de manera similar a AsyncManualResetEvent , excepto que su interfaz está hecha específicamente para este propósito.

es trabajo para mi

  using System; using System.Threading; using System.Threading.Tasks; namespace TaskTest2 { class Program { static ManualResetEvent mre = new ManualResetEvent(false); static void Main(string[] args) { mre.Set(); Task.Factory.StartNew(() => { while (true) { Console.WriteLine("________________"); mre.WaitOne(); } } ); Thread.Sleep(10000); mre.Reset(); Console.WriteLine("Task Paused"); Thread.Sleep(10000); Console.WriteLine("Task Will Resume After 1 Second"); Thread.Sleep(1000); mre.Set(); Thread.Sleep(10000); mre.Reset(); Console.WriteLine("Task Paused"); Console.Read(); } } } 

Ok, tal vez esto merece una respuesta, pero no estoy tan familiarizado con C # y no tengo MonoDevelop aquí, y son las 3 en punto de la mañana, así que tengan compasión.

Estoy sugiriendo algo como esto

 class Spellchecker { private CancellationTokenSource mustStop = null; private volatile Task currentTask = null; //TODO add other state variables as needed public void StartSpellchecker() { if (currentTask != null) { /* * A task is already running, * you can either throw an exception * or silently return */ } mustStop = new CancellationTokenSource(); currentTask = SpellcheckAsync(mustStop.Token); currentTask.Start(); } private async Task SpellcheckAsync(CancellationToken ct) { while (!ct.IsCancellationRequested)) { /* * TODO perform spell check * This method must be the only one accessing * the spellcheck-related state variables */ } currentTask = null; } public async Task StopSpellchecker() { if (currentTask == null) { /* * There is no task running * you can either throw an exception * or silently return */ } else { /* * A CancelAfter(TimeSpan) method * is also available, which might interest you */ mustStop.Cancel(); //Remove the following lines if you don't want to wait for the task to actually stop var task = currentTask; if (task != null) { await task; } } } }