域名解析、异步方法async和await关键字

 域名解析

using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using UnityEngine;

public class Lesson2 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region 知识点一 什么是域名解析?
        //域名解析也叫域名指向、服务器设置、域名配置以及反向IP登记等等
        //说得简单点就是将好记的域名解析成IP
        //IP地址是网络上标识站点的数字地址,但是IP地址相对来说记忆困难
        //所以为了方便记忆,采用域名来代替IP地址标识站点地址。
        //比如 我们要登录一个网页 www.baidu.com 这个就是域名 我们可以通过记忆域名来记忆一个远端服务器的地址,而不是记录一个复杂的IP地址
        //域名解析就是域名到IP地址的转换过程。域名的解析工作由DNS服务器完成
        //我们在进行通信时有时会有需求通过域名获取IP
        //所以这节课我们就来学习C#提供的域名解析相关的类 
        //域名系统(英文:Domain Name System,缩写:DNS)是互联网的一项服务
        //它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网
        //是因特网上解决网上机器命名的一种系统,因为IP地址记忆不方便,就采用了域名系统来管理名字和IP的对应关系
        #endregion
        #region 知识点二 IPHostEntry类
        //命名空间:System.Net
        //类名:IPHostEntry
        //主要作用:域名解析后的返回值 可以通过该对象获取IP地址、主机名等等信息
        //该类不会自己声明,都是作为某些方法的返回值返回信息,我们主要通过该类对象获取返回的信息
        //获取关联IP       成员变量:AddressList
        //获取主机别名列表  成员变量:Aliases
        //获取DNS名称      成员变量:HostName
        #endregion
        #region 知识点三 Dns类
        //命名空间:System.Net
        //类名:Dns
        //主要作用:Dns是一个静态类,提供了很多静态方法,可以使用它来根据域名获取IP地址
        //常用方法
        //1.获取本地系统的主机名
        print(Dns.GetHostName());
        //2.获取指定域名的IP信息
        //根据域名获取
        //同步获取
        //注意:由于获取远程主机信息是需要进行网路通信,所以可能会阻塞主线程
        IPHostEntry entry = Dns.GetHostEntry("www.baidu.com");
        for (int i = 0; i < entry.AddressList.Length; i++)
        {
            print("ip地址:" + entry.AddressList[i]);
        }
        for (int i = 0; i < entry.Aliases.Length; i++)
        {
            print("ip地址:" + entry.Aliases[i]);
        }
        print("DNS服务器名称:" + entry.HostName);
        //异步获取
        GetHostEntry();
        #endregion 
    }
    private async void GetHostEntry()
    {
        Task<IPHostEntry>task = Dns.GetHostEntryAsync("www.baidu.com");
        await task;
        for(int i=0;i<task.Result .AddressList .Length;i++)
        {
            print("ip地址:" + task.Result.AddressList[i]);
        }
        for(int i=0;i<task.Result .Aliases .Length;i++)
        {
            print("ip地址:" + task.Result.Aliases[i]);
        }
        print("DNS服务器名称:" + task.Result.HostName);
    }
    // Update is called once per frame
    void Update()
    {
        
    }
}

异步方法async和await关键字

using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;

public class Lesson2 : MonoBehaviour
{
    CancellationTokenSource source;
    // Start is called before the first frame update
    void Start()
    {
        #region 知识点一 什么是同步和异步
        //同步和异步主要用于修饰方法
        //同步方法:
        //当一个方法被调用时,调用者需要等待该方法执行完毕后返回才能继续执行
        //异步方法:
        //当一个方法被调用时立即返回,并获取一个线程执行该方法内部的逻辑,调用者不用等待该方法执行完毕
        //简单理解异步编程
        //我们会把一些不需要立即得到结果且耗时的逻辑设置为异步执行,这样可以提高程序的运行效率
        //避免由于复杂逻辑带来的的线程阻塞
        #endregion
        #region 知识点二 什么时候需要异步编程
        //需要处理的逻辑会严重影响主线程执行的流畅性时
        //我们需要使用异步编程
        //比如:
        //1.复杂逻辑计算时
        //2.网络下载、网络通讯 
        //3.资源加载时 
        //等等
        #endregion
        #region 知识点三 异步方法async和await
        //async和await一般需要配合Task进行使用
        //async用于修饰函数、lambda表达式、匿名函数
        //await用于在函数中和async配对使用,主要作用是等待某个逻辑结束
        //此时逻辑会返回函数外部继续执行,直到等待的内容执行结束后,再继续执行异步函数内部逻辑
        //在一个async异步函数中可以有多个await等待关键字
        TestAsync();
        print("主线程逻辑执行");
        //使用async修饰异步方法
        //1.在异步方法中使用await关键字(不使用编译器会给出警告但不报错),否则异步方法会以同步方式执行
        //2.异步方法名称建议以Async结尾
        //3.异步方法的返回值只能是void、Task、Task<>
        //4.异步方法中不能声明使用ref或out关键字修饰的变量
        //使用await等待异步内容执行完毕(一般和Task配合使用)
        //遇到await关键字时
        //1.异步方法将被挂起
        //2.将控制权返回给调用者
        //3.当await修饰内容异步执行结束后,继续通过调用者线程执行后面内容
        //举例说明
        //1.复杂逻辑计算(利用Task新开线程进行计算 计算完毕后再使用 比如复杂的寻路算法)
        CalcPathAsync(this.gameObject, Vector3.zero);
        //2.计时器
        Timer();
        print("主线程逻辑执行");
        //3.资源加载(Addressables的资源异步加载是可以使用async和await的)
        //注意:Unity中大部分异步方法是不支持异步关键字async和await的,我们只有使用协同程序进行使用
        //虽然官方 不支持 但是 存在第三方的工具(插件)可以让Unity内部的一些异步加载的方法 支持 异步关键字
        //https://github.com/svermeulen/Unity3dAsyncAwaitUtil
        //虽然Unity中的各种异步加载对异步方法支持不太好
        //但是当我们用到.Net 库中提供的一些API时,可以考虑使用异步方法 
        //1.Web访问:HttpClient 
        //2.文件使用:StreamReader、StreamWriter、JsonSerializer、XmlReader、XmlWriter等等
        //3.图像处理:BitmapEncoder、BitmapDecoder
        //一般.Net 提供的API中 方法名后面带有 Async的方法 都支持异步方法
        #endregion
        #region 总结
        //异步编程async和await是一个比较重要的功能 
        //我们可以利用它配合Task进行异步编程
        //虽然Unity自带的一些异步加载原本是不支持 异步方法关键字的
        //但是可以利用别人写好的第三方工具 让他们支持 大家可以根据自己的需求选择性使用
        #endregion

    }
    private async void TestAsync()
    {
        //1
        print("进入异步方法");
        //2
        await Task.Run(() =>
        {
            Thread.Sleep(5000);
        });
        //3
        print("异步方法后面的逻辑");
    }
    private async void CalcPathAsync(GameObject obj,Vector3 endPos)
    {
        print("开始处理寻路逻辑");
        int value = 10;
        await Task.Run(() =>
      {
          //复杂的寻路算法逻辑,通过休眠模拟算法的复杂性
          Thread.Sleep(1000);
          value = 50;
          //是多线程,意味着我们不能在多线程里去访问Unity主线程场景里的对象
          //这样写会报错
          //print(obj.transform.position);
      });
        print("寻路计算完毕处理逻辑" + value);
        obj.transform.position = Vector3.zero;
    }
    private async void Timer()
    {
        source = new CancellationTokenSource();
        int i = 0;
        while(!source.IsCancellationRequested)
        {
            print(i);
            await Task.Delay(1000);
            ++i;
        }
    }
    // Update is called once per frame
    void Update()
    {
        if(Input .GetKeyDown (KeyCode.Space ))
        {
            source.Cancel();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值