【问题标题】:How to set timeout of soapclient in .net core project如何在.net核心项目中设置soapclient的超时
【发布时间】:2018-06-13 05:42:32
【问题描述】:

我必须在 .Net Core 2.0 项目中使用 SOAP 服务。我添加了以下链接中描述的服务参考:(Missing link, 404)

服务在某些方法上运行良好。但是,某些方法需要很长时间(由于操作服务正在执行),在这种情况下程序会抛出异常:“System.Net.Http.WinHttpException: The operation timed out”

我尝试设置超时值,但没有效果。

MyService.MyServiceSoapClient Pr = 
    new MyService.MyServiceSoapClient(
            new MyService.MyServiceSoapClient.EndpointConfiguration());

Pr.InnerChannel.OperationTimeout = new TimeSpan(0, 10, 0);

我还查看了以下链接,其中包含有关 .Net Core 中 wcf/soap 服务的相关问题:GitHub: dotnet/wcf

但目前还没有解决方案。知道如何解决这个问题吗?

【问题讨论】:

    标签: wcf soap asp.net-core-2.0 timeoutexception


    【解决方案1】:

    好的,如果有人遇到同样的问题,我将发布我找到的解决方案。好像其他人也遇到了这个问题,问了here

    据我了解,这是 .Net Core 2.0 的一般错误,如果请求持续时间超过 30 秒,则会发生此错误。

    如上链接所示,他们发布了解决方案here。它对我有用。解决方案需要在每次发出真实请求之前发出虚假请求以提供服务,以便可以更改超时设置。为避免这种情况,我建议您捕获“CommunicationException”,并在该捕获中应用解决方案。因此,只有在您确实需要时,您才可以拨打额外的电话。我正在复制代码,以防万一链接失效(代码的所有学分到https://github.com/mconnew/

       static void Main(string[] args)
        {
            var client = new SimpleServiceClient();
            client.OpenAsync().GetAwaiter().GetResult();
            client.DelayedResponseAsync(2000).GetAwaiter().GetResult();
            var channel = client.InnerChannel;
            var httpChannelFactory = client.InnerChannel.GetProperty<IChannelFactory>();
            var cacheField = httpChannelFactory.GetType().GetField("_httpClientCache", BindingFlags.NonPublic | BindingFlags.Instance);
            var httpClientCache = cacheField.GetValue(httpChannelFactory);
            var cacheDictionaryField = httpClientCache.GetType().GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance);
    
            IDictionary cacheDictionary = (IDictionary)cacheDictionaryField.GetValue(httpClientCache);
            foreach(var cacheKey in cacheDictionary.Keys)
            {
                var cacheEntry = cacheDictionary[cacheKey];
                var valueField = cacheEntry.GetType().GetField("value", BindingFlags.NonPublic | BindingFlags.Instance);
                HttpClient httpClient = (HttpClient)valueField.GetValue(cacheEntry);
                FixHttpClient(httpClient);
            }
    
            client.DelayedResponseAsync(50000).GetAwaiter().GetResult();
            Console.WriteLine("Done");
            Console.ReadLine();
        }
        private static void FixHttpClient(HttpClient httpClient)
        {
            var handlerField = typeof(HttpMessageInvoker).GetField("_handler", BindingFlags.NonPublic | BindingFlags.Instance);
            DelegatingHandler delegatingHandler = (DelegatingHandler)handlerField.GetValue(httpClient); // Should be of type ServiceModelHttpMessageHandler
            WinHttpHandler winHttpHandler = (WinHttpHandler)delegatingHandler.InnerHandler;
            WinHttpHandler newHandler = new WinHttpHandler();
            newHandler.ServerCredentials = winHttpHandler.ServerCredentials;
            newHandler.CookieUsePolicy = winHttpHandler.CookieUsePolicy;
            newHandler.ClientCertificates.AddRange(winHttpHandler.ClientCertificates);
            newHandler.ServerCertificateValidationCallback = winHttpHandler.ServerCertificateValidationCallback;
            newHandler.Proxy = winHttpHandler.Proxy;
            newHandler.AutomaticDecompression = winHttpHandler.AutomaticDecompression;
            newHandler.PreAuthenticate = winHttpHandler.PreAuthenticate;
            newHandler.CookieContainer = winHttpHandler.CookieContainer;
    
            // Fix the timeouts
            newHandler.ReceiveHeadersTimeout = Timeout.InfiniteTimeSpan;
            newHandler.ReceiveDataTimeout = Timeout.InfiniteTimeSpan;
            newHandler.SendTimeout = Timeout.InfiniteTimeSpan;
    
            var servicemodelHttpHandlerInnerHandlerField = delegatingHandler.GetType().GetField("_innerHandler", BindingFlags.NonPublic | BindingFlags.Instance);
            servicemodelHttpHandlerInnerHandlerField.SetValue(delegatingHandler, newHandler);
            var delegatingHandlerInnerHandlerField = typeof(DelegatingHandler).GetField("_innerHandler", BindingFlags.NonPublic | BindingFlags.Instance);
            delegatingHandlerInnerHandlerField.SetValue(delegatingHandler, newHandler);}
    

    【讨论】:

      【解决方案2】:

      我在客户端对象中找不到 DelayedResponseAsync 方法。但我可以看到 OpenAsync

      【讨论】:

      • 请在您的回答中提供更多详细信息。正如目前所写的那样,很难理解您的解决方案。
      • 我正在尝试使用外部第三方网络服务。我收到异常为“WinHttpException:错误 12002 调用 WINHTTP_CALLBACK_STATUS_REQUEST_ERROR,'操作超时'。System.Threading.Tasks.RendezvousAwaitable.GetResult()”所以,当我开始寻找这个问题的解决方案时,我找到了这篇文章并尝试在我的代码中实现它。根据上面的示例代码,我正在尝试使用“client.DelayedResponseAsync(2000).GetAwaiter().GetResult();”但客户端没有暴露 DelayedResponseAsync 方法。有什么想法吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-01
      • 2022-06-12
      • 1970-01-01
      • 2019-07-14
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多