C# 任务。延迟与任务融合。屈服?

C# 任务。延迟与任务融合。屈服?,c#,task,C#,Task,我正在尝试编写类似光纤的代码,这样我就可以进入任务并从中解脱出来。我尝试的代码: class TaskActivity { CancellationTokenSource _m=new CancellationTokenSource( int.MaxValue ) ,_t=new CancellationTokenSource( int.MaxValue ); public async Task PauseTask( ) { //call and await i

我正在尝试编写类似光纤的代码,这样我就可以进入任务并从中解脱出来。我尝试的代码:

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,因为它在循环中运行,在另一端不会停止。当我尝试
等待Task.Delay(int.MaxValue,(\m\\u t))
而不是
wait Task.Yield()
,它没有消耗很多CPU,但有时它会死锁,因为
任务
不会让位于另一个
任务


我的问题是,如何融合
任务。延迟
任务。产生
,这样它就不会消耗大量CPU,但仍然可以让其他任务工作?

而不是执行while循环,您可以使用
取消令牌
在标记源时通知您:

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;
}
公共任务暂停任务()
{ 
_m、 取消();
_t=新的CancellationTokenSource(int.MaxValue);
//自己做一项任务
var task=new TaskCompletionSource();
_t、 Token.Register(()=>task.TrySetResult(true));//标记任务已完成
返回任务。任务;
}

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

而不是执行while循环,您可以使用
CancellationToken
在标记源时通知您:

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;
}
公共任务暂停任务()
{ 
_m、 取消();
_t=新的CancellationTokenSource(int.MaxValue);
//自己做一项任务
var task=new TaskCompletionSource();
_t、 Token.Register(()=>task.TrySetResult(true));//标记任务已完成
返回任务。任务;
}

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

对于初学者,我感到非常抱歉。当我切换变量并将代码放入
ResumeTask
时,它死锁了。它切换到
任务
,切换回主上下文,再次切换到
任务
,然后死亡。顺便说一下,在主上下文中,我使用了
activity.ResumeTask().Wait()
,可以吗?我不能调用
wait
,因为它在主上下文中,是从
main
方法调用的。我尝试运行了两个任务,但它也死锁了。需要提出新的问题吗?我认为它不适合发表评论。非常抱歉我是初学者。当我切换变量并将代码放入
ResumeTask
时,它死锁了。它切换到
任务
,切换回主上下文,再次切换到
任务
,然后死亡。顺便说一下,在主上下文中,我使用了
activity.ResumeTask().Wait()
,可以吗?我不能调用
wait
,因为它在主上下文中,是从
main
方法调用的。我尝试运行了两个任务,但它也死锁了。需要提出新的问题吗?我认为它不适合评论。仅供参考:。@nosertio看到了这一点,但我想在主上下文和任务之间切换上下文,而不是仅仅恢复和暂停。KugBuBu,如果你是指协同执行(如协同例程),你可能需要检查。还有,还有。您的场景很可能包含在其中一个链接中。我很好,我只需要回答者接受我的编辑,因为他的代码有bug,我会接受它。无论如何谢谢你!不用担心,我只是觉得如果你想让两个任务都保持活动状态,就不应该这样在上下文之间切换。仅供参考:。@nosertio看到了,但我想在主上下文和任务之间切换上下文,而不仅仅是恢复和暂停。KugBuBu,如果你是指协同执行(如协同例程),你可能需要检查一下。还有,还有。您的场景很可能包含在其中一个链接中。我很好,我只需要回答者接受我的编辑,因为他的代码有bug,我会接受它。无论如何谢谢你!不用担心,我只是觉得如果你想让这两项任务都保持活动状态,就不应该这样在上下文之间切换。