c# - 如何正确覆盖自定义 SynchronizationContext 中的 Post 方法?

标签 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 方法微软声明:

When overridden in a derived class, dispatches an asynchronous message to a synchronization context.

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

感谢您的努力!

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

最佳答案

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

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

Post 方法的默认实现是在工作线程上对操作进行排队(通过 ILSpy 获得):

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

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

关于c# - 如何正确覆盖自定义 SynchronizationContext 中的 Post 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35576595/

相关文章:

c# - 如何使用 LibreOffice 和 C# 将 doc 转换为 pdf

javascript - 了解放置 `await` 关键字的位置

java - 如何使用 Jersey Client 2.2.x 取消挂起的异步请求并取消注册调用回调?

c# - C# .NET 中任意长的 Parallel.For 循环

c# - 将变量添加到另一个线程正在使用的列表中,这是不好的做法吗?

c# - 如何使用 C# 和并行扩展并行化顺序任务?

c# - Azure Function 崩溃并出现异常 ""

static string[] contains() (slooooow) 与 == 运算符的 C# 性能

c# - 在 Linq 中将两个 List<object> 合并为一个 List

ajax - 用 Ajax 替换海边的图像