如何在自定义同步上下文中正确重写 Post 方法

本文关键字:重写 Post 方法 上下文 自定义 同步 | 更新日期: 2023-09-27 18:35:53

我一直在研究SynchronizationContext,这些文章(Understanding SynchronizationContext,

ExecutionContext 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方法Microsoft指出:

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

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

感谢您的努力!

后续问题:实现自定义TaskScheduler可能是一种更好的方法 - 也许使用专用线程的 TaskScheduler 本质上是我需要的?

如何在自定义同步上下文中正确重写 Post 方法

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

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

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

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

但最大的问题是为什么需要自己的同步上下文?如果只是为了好玩 - 那很好,否则你正在做非常先进的smth,也许其他现有的更简单的机制可以解决这个问题。