如何在自定义SynchronizationContext中正确覆盖Post方法?

时间:2016-02-23 11:40:28

标签: c# asynchronous task-parallel-library

我一直在调查SynchronizationContext,这些文章(Understanding SynchronizationContextExecutionContext vs SynchronizationContext)确实帮助了我,但是 - 当然 - 还有很多问题。

我想实现自己继承自基类的SynchronizationContext类,以便我可以在任何Task的上下文中使用它(用于自定义消息循环,限制,跟踪等) ;像这样的东西:

public class SyncContext : System.Threading.SynchronizationContext
{

    public SyncContext() : base()
    {
    }

    public override void Send(Threading.SendOrPostCallback d, object state)
    {
        base.Send(d, state);
    }

    public override void Post(Threading.SendOrPostCallback d, object state)
    {
        base.Post(d, state);
    }
}

虽然base.Send似乎符合预期(同步执行回调),但base.Post似乎没有做任何事情。关于微软声明的Post方法:

  

在派生类中重写时,调度异步消息   到同步上下文。

我想基类不能因没有实现异步机制而受到指责,但是在调用base.Post时会发生什么,或者如何正确/更好地实现?我的一般方法是否已经误导了?

感谢您的努力!

后续问题:实施自定义TaskScheduler可能是更好的方法 - 也许TaskScheduler that uses a dedicated thread基本上是我需要的吗?

1 个答案:

答案 0 :(得分:0)

如果您有自己的消息循环,则需要在SynchronizationContext中捕获它,因此当另一个线程调用SynchronizationContext.Post时 - 必须将回调操作添加到该消息循环。

SynchronizationContext"流动"作为ExecutionContext的一部分,但并非总是如此,因此您需要在代码中处理该流程(如果可能的话)。

Post方法的默认实现是在工作线程上排队操作(使用ILSpy获取):

public virtual void Post(SendOrPostCallback d, object state)
{
  ThreadPool.QueueUserWorkItem(new WaitCallback(d.Invoke), state);
}

但最重要的问题是为什么你需要自己的SynchronizationContext?如果它只是为了好玩 - 那很好,否则你会做得非常先进,也许其他现有的更简单的机制可以解决这个问题。