如何在.net核心项目中设置soapclient的超时 [英] How to set timeout of soapclient in .net core project

查看:255
本文介绍了如何在.net核心项目中设置soapclient的超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to use a SOAP service in a .Net Core 2.0 project. I added service reference as described in following link: (Missing link, 404)

对于某些方法,服务运行良好.但是,某些方法会花费很长时间(由于操作服务正在执行),在这种情况下,程序将引发异常:"System.Net.Http.WinHttpException:操作超时"

Service is working fine for some methods. However, some methods are taking long time (due to the operations service is doing) and in this case the program is throwing exception:"System.Net.Http.WinHttpException: The operation timed out"

我试图设置超时值,但是没有效果.

I tried to set the timeout value but it has no effect.

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

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

我还检查了以下链接,该链接具有有关.Net Core中wcf/soap服务的相关问题:

I also checked the folllowing link which has related questions about wcf/soap services in .Net Core: GitHub: dotnet/wcf

但是到目前为止还没有解决方案.知道如何解决这个问题吗?

But no solution so far. Any idea how to solve this problem?

推荐答案

好如果有人遇到相同的问题,我将发布我找到的解决方案.似乎其他人也遇到了这个问题,并在此处

Ok If anyone suffers from the same problem, I am posting the solution I found. It seems other people also faced this problem and asked question here

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

It is a generic error for .Net Core 2.0 as far as i understand and it occurs if request lasts longer than 30 seconds.

从上方的链接中可以看到,他们在此处发布了解决方案.它为我工作.解决方案要求在每次发出真实请求之前都要提出一个虚假请求以进行服务,以便可以更改超时设置.为避免这种情况,我建议您捕获"CommunicationException",然后在该捕获中应用解决方案.因此,只有在确实需要时,您才可以拨打额外的电话.我正在复制代码,以防万一链接消失(代码的所有代码都归功于 https://github.com/mconnew/)

As can be seen in upper link, they posted a solution here. It worked for me. Solution requires to make a fake request to service each time before making a real request so timeout settings can be changed. To avoid that I can suggest you to catch "CommunicationException", and apply the solution in that catch. So you make extra calls only if you really need to. I am copying the code, just in case link dies (all credits for code to 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);}

这篇关于如何在.net核心项目中设置soapclient的超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆