【问题标题】:Wrapping WCF asynchronous call inside task.Factory.FromAsync doesn't return any result在 task.Factory.FromAsync 中包装 WCF 异步调用不返回任何结果
【发布时间】:2016-01-03 03:53:41
【问题描述】:

我有在线程池中调用的 WCF 服务。性能真的很慢。所以想用Task.Factory.FromAsync替换它。但它没有返回任何结果。我从 Silverlight 客户端调用此代码。当我调试代码时,它只是在回调方法中返回异常“远程服务器返回错误:NotFound”。 Fidler 将异常捕获为“验证消息安全性时发生错误

代码没有任何问题,但是性能太低了。

ThreadPool.QueueUserWorkItem((state) =>
        {
            AsyncCallback onEndGetItemProperty = (ar) =>
            {
                try
                {
                    // complete get-item-properties async call
                    topologyItem.ItemProperties = configurationServiceChannel.EndGetItemProperty(ar);
                }
                finally
                {
                    configurationServiceChannel.Close();
                    combineCallback.Decrement();
                }
            };

            // begin get-items-properties async call
            Shell.WSOperation(() =>
                configurationServiceChannel.BeginGetItemProperty(itemId, topologyItem.GetPropertyQueries(), onEndGetItemProperty, configurationServiceChannel),
                configurationServiceChannel);
        });

我已将 Threadpool 替换为 Async。

 Action<IAsyncResult> onEndGetItemProperty = (ar) =>
            {
                try
                {
                    // complete get-item-properties async call
                    topologyItem.ItemProperties = configurationServiceChannel.EndGetItemProperty(ar);
                }
                finally
                {
                    configurationServiceChannel.Close();
                    combineCallback.Decrement();
                }
            };

            // begin get-items-properties async call

           await Task.Factory.FromAsync(configurationServiceChannel.BeginGetItemProperty(itemId, topologyItem.GetPropertyQueries(), null, configurationServiceChannel), onEndGetItemProperty);   

请让我知道我在这里缺少什么。 wcf 配置和安全性非常完美,没有任何问题。只有将其更改为异步后,我才得到结果。

代理:

[System.ServiceModel.OperationContractAttribute(AsyncPattern = true, Action = "http://schemas.microsoft.com/topology/IConfigurationServi" +
        "ce/GetItemProperty", ReplyAction = "http://schemas.microsoft.com//topology/IConfigurationServi" +
        "ce/GetItemPropertyResponse")]
    System.IAsyncResult BeginGetItemProperty(TopologyService.ItemId itemId, System.Collections.ObjectModel.ObservableCollection<TopologyService.ItemPropertyQuery> itemPropertyCriteria, System.AsyncCallback callback, object asyncState);

    System.Collections.ObjectModel.ObservableCollection<TopologyService.ItemProperty> EndGetItemProperty(System.IAsyncResult result);

提前致谢。

【问题讨论】:

  • Turn on WCF tracing 看看发生了什么
  • @Umesh,显示为GetItemProperty 生成的WCF 代理BeginXXX/EndXXX 方法签名。
  • 我启用了 WCF 跟踪,我可以在跟踪中看到以下错误。 " 安全处理器无法在消息中找到安全标头。这可能是因为消息是不安全的错误,或者是因为通信双方之间存在绑定不匹配。如果为安全配置了服务并且客户端是不使用安全性。”
  • 添加服务的代理
  • 异步调用服务不会让服务运行得更快。该服务不知道它被这样调用。这个问题可能没有实际意义。

标签: c# performance wcf task-parallel-library


【解决方案1】:

试试这个:

public static class WcfExt
{
    public static Task<ObservableCollection<TopologyService.ItemProperty>>
        GetItemPropertyAsync(this ConfigurationService @this,
            TopologyService.ItemId itemId,
            ObservableCollection<TopologyService.ItemPropertQuery> itemPropertyCriteria)
    {
        return Task.Factory.FromAsync(
            (asyncCallback, asyncState) =>
                @this.BeginGetItemProperty(
                    itemId, itemPropertyCriteria, 
                    asyncCallback, asyncState),
            (asyncResult) =>
                @this.EndGetItemProperty(asyncResult), null);
    }
}

// ... 
// calling it
try 
{           
    topologyItem.ItemProperties = await configurationServiceChannel.GetItemPropertyAsync(
        itemId, itemPropertyCriteria);
}
finally
{
    configurationServiceChannel.Close();
}

【讨论】:

  • FromAsync 调用看起来更明智。另一种选择是生成支持 TAP 模式的代理。
猜你喜欢
  • 1970-01-01
  • 2021-07-31
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-07
  • 1970-01-01
  • 2018-09-01
相关资源
最近更新 更多