C#中异步调用API且非阻塞UI

1、说明

在实际的使用过程中,都会存在第三方的API的情况,但第三方API可能存在网络及本身的异常,造成UI阻塞。本篇主要解决异步调用API且不阻塞UI的相关知识。

2、具体实现

2.1 前提说明

1、开发环境:VS2019、.NET Framework4.5、win10企业版
2、webapi
先创建了一个webapi,内容非常简单

public class ZLController : ApiController
{
    public string getZL()
    {
        var temp = new { id = "123", name = "郑林" };


        Thread.Sleep(5000);

        return JsonConvert.SerializeObject(temp);
    }
}

4、效果如下
招聘

2.1 使用HttpClient

1、HttpClient是在.NET Framework4.5中增加的。因此需要注意本地.NET Framework的版本。
2、HttpClient类中的方法均为异步。
3、效果如下如下:
在这里插入图片描述
4、代码如下:

private async void asyncButtonClick(object sender, EventArgs e)
{
    try
    {
        string resultStr = await httpClient.GetStringAsync("http://localhost/SomeApiDemo/api/zl/getzl");

        this.label1.Text = resultStr;
    }
    catch (Exception ex)
    {
        if (ex is System.Threading.Tasks.TaskCanceledException)
        {
            MessageBox.Show("通信接口延迟timeOut后,仍无回复");
        }
        else
        {
            MessageBox.Show(ex.Message);
        }
    }
}

2.2 使用WebRequest

WebRequest是从.NET Framework1.0就有了。

1、效果
图片
2、代码

private void button5_Click(object sender, EventArgs e)
{
    //写法1
    Task<string> testtask = new Task<string>(syncWebRequest);//具体执行方法
    testtask.ContinueWith(myaction, m_syncContextTaskScheduler);//成功后的回调方法
    testtask.Start();
}

syncWebRequest方法的内容:

//调用API,并进行返回的方法--供方法2和方法3使用
private string syncWebRequest()
{
    string getdata = "";
    try { 
        WebRequest request = WebRequest.Create("http://localhost/SomeApiDemo/api/zl/getzl");
        request.Timeout = 10000;

        //请求,并获取数据
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        Stream dataStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(dataStream);
        
        getdata = reader.ReadToEnd();
    
        reader.Close();
        dataStream.Close();
        response.Close(); 
    }catch(Exception ex)
    {
        if(ex.Message=="操作超时")
        {
            getdata = "通信接口延迟timeOut后,仍无回复";
        }
        else
        {
            getdata = ex.Message;
        }
    }
    return getdata;
}

myaction的回调方法

//成功之后的回调方法
private void myaction(Task<string> mytask)
{
    this.label4.Text = mytask.Result;
}

3、代码下载

代码下载

4、其他

在网上看到另外一个可以结束Task的方法,很好玩。

namespace Walterlv
{
    public static class TaskWaitingExtensions
    {
        public static async Task<TResult> WaitAsync<TResult>(this Task<TResult> task, TimeSpan timeout)
        {
            using (var timeoutCancellationTokenSource = new CancellationTokenSource())
            {
                var delayTask = Task.Delay(timeout, timeoutCancellationTokenSource.Token);
                if (await Task.WhenAny(task, delayTask) == task)
                {
                    timeoutCancellationTokenSource.Cancel();
                    return await task;
                }
                throw new TimeoutException("The operation has timed out.");
            }
        }
    }
}

这个是异步设置timeout的方法,最关键的使用了两个方法:Task.DelayTask.WhenAny。非常巧妙的实现了定时的功能。本质上直接干翻task,根本不关心task承载的内容。刚才提到的连接在这儿

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值