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,我会接受它。无论如何谢谢你!不用担心,我只是觉得如果你想让这两项任务都保持活动状态,就不应该这样在上下文之间切换。