c# - 将 OperationContext 传播到异步 WCF 调用中

标签 c# wcf async-await c#-5.0 operationcontext

使用 WCF 中的 C#5 Async-Await,如果其余代码在不同的线程上继续执行等待,我们将释放当前操作上下文。 (OperationContext.Current 为空)。

我正在开发调用另一个外部服务的 WCF 服务。并且在访问操作上下文的外部服务调用中使用了一些自定义绑定(bind)扩展。因此,我需要在此调用期间传播上下文,它不能仅将操作上下文复制到局部变量中。

我的配置是这样的

<system.serviceModel>
<bindings>
  <customBinding>
<binding name="MyCustomBinding">
      <MyBindingExtention/>
      <security authenticationMode="UserNameOverTransport" />
      <textMessageEncoding maxReadPoolSize="64" >
        <readerQuotas maxStringContentLength="8192" />
      </textMessageEncoding>
      <httpsTransport manualAddressing="false" maxReceivedMessageSize="65536" />
    </binding>
 </customBinding>
 <client>
  <endpoint address="https://ExternalService.svc" binding="customBinding" bindingConfiguration="MyCustomBinding" contract="Contract" name="ExternalService"/>
 </client>
 </bindings> 
<extensions>
 <bindingElementExtensions>
    <add name="MyBindingExtention" type="Bindings.MyBindingExtention, Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
  </bindingElementExtensions>  
</extensions>   
</system.serviceModel>

其中“MyBindingExtention” 访问operationcontext 以获取一些信息。

public async Task<string> GetExternalData(int value)
{
    var oc = OperationContext.Current;

    //External Web service Call
    var response = await externalService.GetDataAsync();

    return response.text;
}

有没有一种好方法可以使 OperationContext 传播到外部服务调用,然后再次传播到剩余的代码执行中?

最佳答案

您可以使用自定义同步上下文。下面是一个示例 SynchronizationContext 实现:

public class OperationContextSynchronizationContext : SynchronizationContext
{
    private readonly OperationContext context;

    public OperationContextSynchronizationContext(IClientChannel channel) : this(new OperationContext(channel)) { }

    public OperationContextSynchronizationContext(OperationContext context)
    {
        OperationContext.Current = context;
        this.context = context;
    }

    public override void Post(SendOrPostCallback d, object state)
    {
        OperationContext.Current = context;
        d(state);
    }
}

和用法:

var currentSynchronizationContext = SynchronizationContext.Current;
try
{
    SynchronizationContext.SetSynchronizationContext(new OperationContextSynchronizationContext(client.InnerChannel));
    var response = await client.RequestAsync();
    // safe to use OperationContext.Current here
}
finally
{
    SynchronizationContext.SetSynchronizationContext(currentSynchronizationContext);
}

关于c# - 将 OperationContext 传播到异步 WCF 调用中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20877027/

相关文章:

c# - 数据未使用 TcpClient 在 LAN 上完全传输

c# - System.Drawing Out of Memory Exception on Main() 方法 - C#

amazon-web-services - Amazon EC2 上 Windows 服务中的 WCF 服务

c# - 与 WPF 属性异步

javascript - 如果异步函数出错,如何执行代码块

javascript - 如何使用 async/await 处理错误?

c# - 从代码创建 Azure Redis 缓存

C#:linq 返回 bool 值而不是字符串

.net - 如何使用远程服务器的 net.tcp 端点 ping 或检查 WCF 服务的状态?

c# - WCF 定义多个具有不同 ServiceContract 类型的 ServiceContract