A pattern for self-cancelling and restarting task

后端 未结 4 987
醉酒成梦
醉酒成梦 2020-11-30 01:38

Is there a recommended established pattern for self-cancelling and restarting tasks?

E.g., I\'m working on the API for background spellchecker. The spellcheck sessio

4条回答
  •  孤独总比滥情好
    2020-11-30 01:49

    I think the general concept is pretty good, though I recommend you not use ContinueWith.

    I'd just write it using regular await, and a lot of the "am I already running" logic is not necessary:

    Task pendingTask = null; // pending session
    CancellationTokenSource cts = null; // CTS for pending session
    
    // SpellcheckAsync is called by the client app on the UI thread
    public async Task SpellcheckAsync(CancellationToken token)
    {
        // SpellcheckAsync can be re-entered
        var previousCts = this.cts;
        var newCts = CancellationTokenSource.CreateLinkedTokenSource(token);
        this.cts = newCts;
    
        if (previousCts != null)
        {
            // cancel the previous session and wait for its termination
            previousCts.Cancel();
            try { await this.pendingTask; } catch { }
        }
    
        newCts.Token.ThrowIfCancellationRequested();
        this.pendingTask = SpellcheckAsyncHelper(newCts.Token);
        return await this.pendingTask;
    }
    
    // the actual task logic
    async Task SpellcheckAsyncHelper(CancellationToken token)
    {
        // do the work (pretty much IO-bound)
        using (...)
        {
            bool doMore = true;
            while (doMore)
            {
                token.ThrowIfCancellationRequested();
                await Task.Delay(500); // placeholder to call the provider
            }
            return doMore;
        }
    }
    

提交回复
热议问题