【问题标题】:Task.Delay fused with Task.Yield?Task.Delay 与 Task.Yield 融合了吗?
【发布时间】:2014-07-15 13:07:01
【问题描述】:

我正在尝试编写类似光纤的代码,以便我可以进入任务并摆脱它。我试过的代码:

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,但仍然可以让其他任务工作?

【问题讨论】:

  • @Noseratio 看到了,但我想在主上下文和任务之间切换上下文,而不仅仅是恢复和暂停。
  • KugBuBu,如果您的意思是协同执行(如协程),您可能需要检查this。另外,thisthis。这些链接之一很可能涵盖了您的方案。
  • @Noseratio 好吧,我很好,我只需要那个回答者接受我的编辑,因为他的代码有错误,我会接受。还是谢谢!
  • 不用担心,只是我不认为这是你应该在上下文之间切换的方式,如果你想保持两个任务都处于活动状态。

标签: c# task


【解决方案1】:

您可以使用RegisterCancellationToken 在标记源时通知您,而不是执行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;
}

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

【讨论】:

  • 我很抱歉成为初学者。当我切换变量并将代码放入ResumeTask 时,它陷入了僵局。它切换到Task,切换回主上下文,再次切换到Task,然后死了。顺便说一下我用activity.ResumeTask( ).Wait( );的主要语境,可以吗?
  • 我无法调用await,因为它在主上下文中,它是来自Main 方法的调用。
  • 我尝试运行两个任务,它也死锁了。需要打开新问题吗?我认为它不适合 cmets。
猜你喜欢
  • 2013-09-02
  • 2015-01-04
  • 2012-10-18
  • 1970-01-01
  • 1970-01-01
  • 2020-05-26
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
相关资源
最近更新 更多