Unity 将UnityWebRequest改为async/await异步
花了一点时间,对UnityWebRequest进行了简单封装,使用起来更方便一些,顺便实现了post接口轮询、重试的功能
using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using UnityEngine; using UnityEngine.Networking; public static class WebRequest { public class Result { public long code; public string message; public byte[] data; public string GetText() { if (data != null && data.Length != 0) { return Encoding.UTF8.GetString(data, 0, data.Length); } return ""; } } public class LoopArgs { /// <summary> /// 循环多少次,为0时表示无限循环 /// </summary> public ushort Count { get; private set; } /// <summary> /// 每次循环间隔多少毫秒 /// </summary> public ushort MsDelay { get; private set; } /// <summary> /// 直到返回true时终止循环,该方法允许根据每次结果,设置终止循环的时机,在小于循环次数时提前结束循环 /// </summary> public Func<Result, bool> AbortUntil { get; private set; } public LoopArgs(ushort count, ushort msDelay, Func<Result, bool> abortUntil) { Count = count; MsDelay = msDelay; AbortUntil = abortUntil; } } public static async Task<Result> Post(string url, WWWForm form, Dictionary<string, string> headers) { using (UnityWebRequest request = UnityWebRequest.Post(url,form)) { if (headers != null) { foreach (KeyValuePair<string, string> item in headers) { request.SetRequestHeader(item.Key, item.Value); } } await request.SendWebRequest(); Result result = new Result(); result.code = request.responseCode; result.message = request.result.ToString(); result.data = request.downloadHandler.data; return result; } } public static async Task<Result> Post(string url, WWWForm form, Dictionary<string, string> headers, LoopArgs loopArgs = null) { return await Loop(() => { return Post(url, form, headers); }, loopArgs); } static async Task<Result> Loop(Func<Task<Result>> request, LoopArgs loopArgs) { Result result; if (loopArgs == null) { result = await request(); } else { ushort i = 0; while (true) { result = await request(); if (loopArgs.AbortUntil != null && loopArgs.AbortUntil.Invoke(result)) { break; } if (loopArgs.Count != 0 && i >= loopArgs.Count) { break; } await Task.Delay(loopArgs.MsDelay); i++; } } return result; } /// <summary> /// 异步的扩展方法 /// </summary> public static TaskAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOp) { var tcs = new TaskCompletionSource<object>(); asyncOp.completed += obj => { tcs.SetResult(null); }; return ((Task)tcs.Task).GetAwaiter(); } }
这样调用
using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; using UnityEngine; public class Test : MonoBehaviour { void Start() { Debug.LogError("开始请求"); PostTest(); Debug.LogError("调用结束"); } async void PostTest() { Debug.LogError("开始"); WebRequest.Result result = await WebRequest.Post("www.baidu.com", null, null, new WebRequest.LoopArgs(3, 1000, (r) => { Debug.LogError(r.message); return false; })); string content = result.GetText(); Debug.LogError("结束: " + content); } }
打印结果:
UnityWebRequest在IEnumerator方法中调用的重试,看我这篇文章:https://www.cnblogs.com/Jason-c/p/17965016
博客园Jason_c微信打赏码
如果本篇文档对你有帮助,打赏Jason_c根华子吧,他的私房钱被老婆没收了,呜呜!