异步服务器方法中使用的 SynchronizationContext

SynchronizationContext used in asynchronous server methods

所以我有一个异步 grpc C# 服务器,它需要在服务器方法之间进行大量串扰(例如,流 rpc 的流响应值可以从另一个 rpc 生成)。

我已经尝试将 SynchronizationContext 设置为基于单线程的上下文,但服务器方法似乎仍然是从任意线程调用的。

我如何确保所有服务器方法都在同一线程上调用,并且 async/await 延续也在同一线程上?

例如,查看以下 RPC 处理程序:

public override Task<ResponseProto> TestRpc(RequestProto request, ServerCallContext context)
{
    // Call shared instance method - could be called from
    // multiple concurrent grpc requests, or streamed responses etc
    SharedInstanceMethod();

    // This is different every call... making a cross-thread issue
    // when calling SharedInstanceMethod();
    int threadId = Thread.CurrentThread.ManagedThreadId; 
}

请注意,在此示例中,SharedInstanceMethod() 是许多其他函数和其他异步事件的占位符 - 我不希望使 SharedInstance 线程安全。

要在同一线程上继续 运行,您可以使用 JoinableTaskFactory.Run(() => ...) from vs-threading,它设置 SynchronizationContext 来实现此目的。

一个问题是,一旦你点击 .ConfigureAwait(false),你就会失去这个上下文,并且继续将结束 运行回到线程池线程,所以如果你是调用 3rd 方库那么你不能保证这种行为,如果他们遵循最佳实践,那么他们可能会使用 .ConfigureAwait(false).

但是回到你的问题,我认为这不是你想要的。听起来您没有需要在 1 个线程上同步强制 运行 的异步工作流(这很好,因为它并不理想)。你有一个不能并发调用的方法,需要围绕它进行一些同步,你应该使用 lock 并添加一个私有静态对象字段来锁定。