的任务.延迟与任务融合

本文关键字:任务 融合 延迟 | 更新日期: 2023-09-27 18:05:19

我正在尝试做类似纤维的代码,我可以进入任务和退出它。我试过的代码:

class TaskActivity {
    CancellationTokenSource _m=new CancellationTokenSource( int.MaxValue )
        ,_t=new CancellationTokenSource( int.MaxValue );
    public async Task PauseTask( ) { //call and await it when I want to pause task inside itself
        _m.Cancel( );
        _t = new CancellationTokenSource( int.MaxValue );
        while( !_t.IsCancellationRequested )
            await Task.Yield( );
    }
    public async Task ResumeTask( ) { //call and wait for it when I want to resume a task from the main context
        _t.Cancel( );
        _m = new CancellationTokenSource( int.MaxValue );
        while( !_m.IsCancellationRequested )
            await Task.Yield( );
    }
}

它工作得很好,但是当我在Task'Main上下文中调用Thread.Sleep时,它会消耗大量CPU,因为它在循环中运行而不会在另一边停止。当我尝试await Task.Delay( int.MaxValue, (_m'_t) );而不是await Task.Yield( );时,它没有消耗大量CPU,但有时会因为Task不屈服于另一个Task而死锁。

我的问题是,如何融合Task.DelayTask.Yield,这样它就不会消耗大量的CPU,但仍然能够让其他任务工作?

的任务.延迟与任务融合

代替while循环,您可以使用RegisterCancellationToken来通知您何时标记源:

public Task PauseTask( ) 
{ 
    _m.Cancel( );
    _t = new CancellationTokenSource( int.MaxValue );
    // Make a task yourself
    var task = new TaskCompletionSource<bool>();
    _t.Token.Register(() => task.TrySetResult(true)); // Mark the task done
    return task.Task;
}

这避免了您通过whileTask.Yield使用的有效旋转等待,并在取消发生时直接标记任务完成。