Winform中使用HttpClient(设置最大超时响应时间)调用接口并做业务处理时界面卡住,使用async Task await异步任务编程优化

这篇具有很好参考价值的文章主要介绍了Winform中使用HttpClient(设置最大超时响应时间)调用接口并做业务处理时界面卡住,使用async Task await异步任务编程优化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

场景

Winform中怎样使用HttpClient调用http的get和post接口并将接口返回json数据解析为实体类:

Winform中怎样使用HttpClient调用http的get和post接口并将接口返回json数据解析为实体类_winform请求http接口_霸道流氓气质的博客-CSDN博客

参考前面使用HttpClient调用http的get和post接口的小示例,

需要定位调用http的get接口并对接口返回数据进行后续处理。

关于定时器的使用在下面文章中有涉及到

Winform中使用mysqldump实现选择部分表定期备份mysql数据库:

Winform中使用mysqldump实现选择部分表定期备份mysql数据库_mysqldump 部分表_霸道流氓气质的博客-CSDN博客

注:

博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主

实现

1、初次业务实现逻辑比较简单,未考虑任务同步执行堵塞UI线程的情况。

在测试时发现,当http接口不通时,而又未设置httpClient的最大超时响应时间,

会导致页面卡死无响应。

优化前的代码:

        private void convertPositionControl() {
            try
            {
                //获取接口数据
                var positionData = requestGetHttpData(positionCalculateUrl);
                //http请求不到数据,啥也不干
                if (null == positionData)
                {
                    return;
                }//请求到数据,则进行数据处理
                else
                {
 
                }
            }
            catch (Exception exception)
            {
                textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":获取接口出错:");
                textBox_log.AppendText("\r\n");
                textBox_log.AppendText(exception.Message);
            }
        }

上面是在定时器中具体执行的代码,省略部分逻辑,其中请求http接口的方法是

requestGetHttpData,参数getAllBaseStationInfoUrl是接口url。

然后请求接口的方法具体实现是

        private string requestGetHttpData(string apiUrl)
        {
            try {
                //调用接口请求数据
                var originAddressUrl = apiUrl;
                //请求接口数据
                if (null == httpClient) {
                    httpClient = new HttpClient();
                }
                var url = new Uri(originAddressUrl);
                var response = httpClient.GetAsync(url).Result;
                var data = response.Content.ReadAsStringAsync().Result;
                return data;
            }
            catch (Exception exception) {   
                textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":调用接口" + apiUrl + "异常:" + exception.Message);
                textBox_log.AppendText("\r\n");
                return null;
            }
        }

这里直接未作任何考虑,只是考虑接口正常的情况。

但是当接口不存在或者报错时就会导致页面卡死。

注意:

HttpClient的预热机制,不要在每次请求接口时都要初始化

httpClient = new HttpClient();

这里放在页面加载完成之后进行初始化一次

        private void Form1_Load(object sender, EventArgs e)
        {
            httpClient = new HttpClient();
            httpClient.Timeout = TimeSpan.FromSeconds(httpClientMaxResponseSeconds);
        }

另外需要给httpClient设置最大响应超时时长

2、C# 中 HttpClient设置最大响应超时时长

 httpClient.Timeout = TimeSpan.FromSeconds(httpClientMaxResponseSeconds);

这里httpClientMaxResponseSeconds是

private double httpClientMaxResponseSeconds = 2;

这里设置为2秒。

后续建议将其优化为单例模式或其他更好的模式。

3、上面卡住问题是因为在同步执行的方法中,请求接口的方法会堵塞UI线程/主线程。

需要将上面请求接口的方法修改成异步任务执行的机制,避免影响UI线程。

这块在之前写mqtt连接时用到到,但是当时不知其所以然。

c# httpclient 超时,C#,ui,json,java 

Winform中使用MQTTnet实现MQTT的服务端和客户端之间的通信以及将订阅的消息保存到文件:

Winform中使用MQTTnet实现MQTT的服务端和客户端之间的通信以及将订阅的消息保存到文件_mqtt winform_霸道流氓气质的博客-CSDN博客

4、异步

同步和异步主要用于修饰方法。当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,

我们称这个方法是同步方法;当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,

调用者不用等待该方法执行完毕,我们称这个方法为异步方法。

异步的好处在于非阻塞(调用线程不会暂停执行去等待子线程完成),因此我们把一些不需要立即使用结果、

较耗时的任务设为异步执行,可以提高程序的运行效率。net4.0在ThreadPool的基础上推出了Task类,

微软极力推荐使用Task来执行异步任务,现在C#类库中的异步方法基本都用到了Task;net5.0推出了async/await,

让异步编程更为方便。

在C#5.0中出现的 async和await ,让异步编程变得更简单。

关于async Task 和await的使用不再详述,具体可自行学习。

下面参考一个网络上的示例

class Program
    {
        static void Main(string[] args)
        {
            string content = GetContentAsync(Environment.CurrentDirectory + @"/test.txt").Result;
            //调用同步方法
            //string content = GetContent(Environment.CurrentDirectory + @"/test.txt");
            Console.WriteLine(content);
            Console.ReadKey();
        }
        //异步读取文件内容
        async static Task<string> GetContentAsync(string filename)
        {
           
            FileStream fs = new FileStream(filename, FileMode.Open);
            var bytes = new byte[fs.Length];
            //ReadAync方法异步读取内容,不阻塞线程
            Console.WriteLine("开始读取文件");
            int len = await fs.ReadAsync(bytes, 0, bytes.Length);
            string result = Encoding.UTF8.GetString(bytes);
            return result;
        }
        //同步读取文件内容
        static string GetContent(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open);
            var bytes = new byte[fs.Length];
            //Read方法同步读取内容,阻塞线程
            int len =  fs.Read(bytes, 0, bytes.Length);
            string result = Encoding.UTF8.GetString(bytes);
            return result;
        }
    }

优化代码

首先将HttpClient修改为单例模式,避免每次请求接口都去new

新建类

{

    class Global
    {

        private static string _lockFlag = "GlobalLock";

        private static Global _instance;


        //http请求客户端
        public HttpClient httpClient = new HttpClient();

        private Global()
        {

        }

        public static Global Instance
        {
            get
            {
                lock (_lockFlag)
                {
                    if (_instance == null)
                    {
                        _instance = new Global();
                    }
                    return _instance;
                }
            }
        }

    }
}

关于全局/单例的实现可以参考如下:

C#中全局作用域的常量、字段、属性、方法的定义与使用:

C#中全局作用域的常量、字段、属性、方法的定义与使用_霸道流氓气质的博客-CSDN博客

这里就一个窗体,所以在窗体初始化后设置其响应时长,也可放在全局工具类的get方法中

        private void Form1_Load(object sender, EventArgs e)
        {
            //设置http连接超时时间
            Global.Instance.httpClient.Timeout = TimeSpan.FromSeconds(httpClientMaxResponseSeconds);
        }

然后改造请求Http接口的方法

        private async Task<string> requestGetHttpData(string apiUrl)
        {
            try {
                var originAddressUrl = apiUrl;
                //请求接口数据        
                var url = new Uri(originAddressUrl);
                string jsonResponse = await Global.Instance.httpClient.GetStringAsync(url);
                return jsonResponse;
            }
            catch (Exception exception) {

                textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":调用接口" + apiUrl + "异常:" + exception.Message);
                textBox_log.AppendText("\r\n");
                
                return null;
            }
        }

将方法添加async Task<string>,注意这里httpClient调用GetStringAsync方法前面加了await

然后定时器执行中的方法调用修改为

        private async Task convertPositionControl() {
            try
            {
                //获取接口数据
                var positionData = await requestGetHttpData(positionCalculateUrl);
                //http请求不到数据,啥也不干
                if (null == positionData)
                {
                    return;
                }//请求到数据,则进行数据处理
                else
                {
                   
                }
            }
            catch (Exception exception)
            {
                textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":获取接口出错:");
                textBox_log.AppendText("\r\n");
                textBox_log.AppendText(exception.Message);
            }
        }

至此,不会导致界面卡住的现象。文章来源地址https://www.toymoban.com/news/detail-788492.html

到了这里,关于Winform中使用HttpClient(设置最大超时响应时间)调用接口并做业务处理时界面卡住,使用async Task await异步任务编程优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue请求时间太长_接口处理请求时间过长,前台响应“服务器超时”的解决办法

    这些方法可以根据具体需求和情况进行选择和组合使用,以提高前端的用户体验和接口的性能。同时,还需要考虑服务器端的性能和网络环境,以及前后端的协作来实现最佳的用户体验。

    2024年02月09日
    浏览(63)
  • 前端页面超时时间设置

    有志者,事竟成 文章持续更新,可以关注【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。 在项目中我们经常会有超时的情况发生,例如点击某一个查询按钮,然后

    2024年02月11日
    浏览(48)
  • 设置RabbitMQ超时时间

    RabbitMQ默认的超时时间是30分钟,在消息消费超过30分钟后,rabbitMQ会发生错误,导致整个channel被销毁,无法继续消费 在RabbitMQ安装的终端执行 命令,将超时时间延长。 使用 可以查看设置的超时值。 值得注意的是,这个事临时更改,永久更改需要进入 rabbitmq.con f 文件里修改

    2024年02月04日
    浏览(41)
  • axios设置超时时间

    方式一: 方式二: 3.创建实例 可以使用自定义配置新建一个 axios 实例 : axios.create([config]) 4.判断超时

    2024年02月12日
    浏览(49)
  • 【Jenkins】Pipeline - 设置超时时间

    默认时间单位为 MINUTES ,如果其他时间单位,则使用 unit 参数:SECONDS、MINUTES和HOURS 可以在不同级别(每个整体管道或每个阶段)使用options指定超时 在上面的示例中,在阶段超时之后,流水线中止,并显示以下消息: Sending interrupt signal to process Cancelling nested steps due to timeout 如果

    2024年02月17日
    浏览(45)
  • 【JAVA】设置http超时时间

    setConnectTimeout:设置连接超时时间,单位毫秒。 setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。 setSocketTimeout:请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无

    2024年02月11日
    浏览(45)
  • axios 设置超时时间 timeout

    在项目中,所有请求都是走统一封装过的axios,统一设置了超时时间: 但是有一个接口耗费时间巨长,网络不好时经常会超时,改统一设置的超时时间感觉不太好,所以想针对这个请求单独设置超时时间。 以下是普通请求: 单独设置请求超时时间:

    2024年02月16日
    浏览(44)
  • CSDN博客批量查询质量分https://yma16.inscode.cc/请求超时问题(设置postman超时时间)(接口提供者设置了nginx超时时间)

    https://yma16.inscode.cc/ 查询别人的一下子就返回了,查询我自己的,1分钟还不返回,然后就显示超时了。。 一开始我还以为是这个开源项目本身的问题,设置了请求超时时间,我还给它改了超时时间,后来发现不是的。。。 本来是100000的,我给改成1000000了,我对js代码不熟,

    2024年02月12日
    浏览(56)
  • python requests设置连接超时时间

    这段代码的主要作用是使用requests库发出一个GET请求,并设置连接超时时间为5秒钟,读取超时时间为10秒钟。 如果请求超时,就会抛出requests.exceptions.Timeout异常,并在\\\"except\\\"语句块中进行处理。如果发生其他类型的错误,如连接错误,就会抛出requests.exceptions.ConnectionError异常,

    2024年02月13日
    浏览(61)
  • Axios设置请求超时时间 timeout

    1.axios全局设置网络超时 2. 单独对某个请求设置网络超时 3.webpack的dev的proxyTable的超时时间设置

    2024年04月10日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包