异步服务器方法中使用的 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
并添加一个私有静态对象字段来锁定。
所以我有一个异步 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
并添加一个私有静态对象字段来锁定。