From aabd25d2e8d1df9af2260e73dfd5ea11dd4f663f Mon Sep 17 00:00:00 2001 From: oneRain Date: Fri, 6 Sep 2019 12:24:50 +0800 Subject: [PATCH] * AWSUploader.cs: chore: await/async * AVFile.cs: * AVCloud.cs: * AVQuery.cs: * AVLeaderboard.cs: * QiniuUploader.cs: * QCloudUploader.cs: --- .../Internal/File/Controller/AWSUploader.cs | 6 +- .../File/Controller/QCloudUploader.cs | 64 +++---- .../Internal/File/Controller/QiniuUploader.cs | 48 +++-- Storage/Storage/Public/AVCloud.cs | 57 +++--- Storage/Storage/Public/AVFile.cs | 15 +- Storage/Storage/Public/AVQuery.cs | 85 ++++----- .../Public/LeaderBoard/AVLeaderboard.cs | 168 ++++++++---------- 7 files changed, 201 insertions(+), 242 deletions(-) diff --git a/Storage/Storage/Internal/File/Controller/AWSUploader.cs b/Storage/Storage/Internal/File/Controller/AWSUploader.cs index 7cad558..92ba983 100644 --- a/Storage/Storage/Internal/File/Controller/AWSUploader.cs +++ b/Storage/Storage/Internal/File/Controller/AWSUploader.cs @@ -8,15 +8,13 @@ using System.Net.Http.Headers; namespace LeanCloud.Storage.Internal { internal class AWSUploader : IFileUploader { - public Task Upload(FileState state, Stream dataStream, IDictionary fileToken, IProgress progress, + public async Task Upload(FileState state, Stream dataStream, IDictionary fileToken, IProgress progress, CancellationToken cancellationToken) { var uploadUrl = fileToken["upload_url"].ToString(); state.ObjectId = fileToken["objectId"].ToString(); string url = fileToken["url"] as string; state.Url = new Uri(url, UriKind.Absolute); - return PutFile(state, uploadUrl, dataStream).OnSuccess(s => { - return s.Result; - }); + return await PutFile(state, uploadUrl, dataStream); } internal async Task PutFile(FileState state, string uploadUrl, Stream dataStream) { diff --git a/Storage/Storage/Internal/File/Controller/QCloudUploader.cs b/Storage/Storage/Internal/File/Controller/QCloudUploader.cs index 6f47b42..fe5e7b2 100644 --- a/Storage/Storage/Internal/File/Controller/QCloudUploader.cs +++ b/Storage/Storage/Internal/File/Controller/QCloudUploader.cs @@ -19,26 +19,28 @@ namespace LeanCloud.Storage.Internal { bool done; private long sliceSize = (long)CommonSize.KB512; - public Task Upload(FileState state, Stream dataStream, IDictionary fileToken, IProgress progress, CancellationToken cancellationToken) { + public async Task Upload(FileState state, Stream dataStream, IDictionary fileToken, IProgress progress, CancellationToken cancellationToken) { fileState = state; data = dataStream; uploadUrl = fileToken["upload_url"].ToString(); token = fileToken["token"].ToString(); fileState.ObjectId = fileToken["objectId"].ToString(); bucket = fileToken["bucket"].ToString(); - - return FileSlice(cancellationToken).OnSuccess(t => { - if (done) return Task.FromResult(state); - var response = t.Result.Item2; - var resumeData = response["data"] as IDictionary; - if (resumeData.ContainsKey("access_url")) return Task.FromResult(state); - var sliceSession = resumeData["session"].ToString(); - var sliceOffset = long.Parse(resumeData["offset"].ToString()); - return UploadSlice(sliceSession, sliceOffset, dataStream, progress, cancellationToken); - }).Unwrap(); + var result = await FileSlice(cancellationToken); + if (done) { + return state; + } + var response = result.Item2; + var resumeData = response["data"] as IDictionary; + if (resumeData.ContainsKey("access_url")) { + return state; + } + var sliceSession = resumeData["session"].ToString(); + var sliceOffset = long.Parse(resumeData["offset"].ToString()); + return await UploadSlice(sliceSession, sliceOffset, dataStream, progress, cancellationToken); } - Task UploadSlice( + async Task UploadSlice( string sessionId, long offset, Stream dataStream, @@ -55,21 +57,20 @@ namespace LeanCloud.Storage.Internal { } if (offset == dataLength) { - return Task.FromResult(fileState); + return fileState; } var sliceFile = GetNextBinary(offset, dataStream); - return ExcuteUpload(sessionId, offset, sliceFile, cancellationToken).OnSuccess(_ => { - offset += sliceFile.Length; - if (offset == dataLength) { - done = true; - return Task.FromResult(fileState); - } - var response = _.Result.Item2; - var resumeData = response["data"] as IDictionary; - var sliceSession = resumeData["session"].ToString(); - return UploadSlice(sliceSession, offset, dataStream, progress, cancellationToken); - }).Unwrap(); + var result = await ExcuteUpload(sessionId, offset, sliceFile, cancellationToken); + offset += sliceFile.Length; + if (offset == dataLength) { + done = true; + return fileState; + } + var response = result.Item2; + var resumeData = response["data"] as IDictionary; + var sliceSession = resumeData["session"].ToString(); + return await UploadSlice(sliceSession, offset, dataStream, progress, cancellationToken); } Task>> ExcuteUpload(string sessionId, long offset, byte[] sliceFile, CancellationToken cancellationToken) { @@ -81,19 +82,18 @@ namespace LeanCloud.Storage.Internal { return PostToQCloud(body, sliceFile, cancellationToken); } - Task>> FileSlice(CancellationToken cancellationToken) { + async Task>> FileSlice(CancellationToken cancellationToken) { SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider(); var body = new Dictionary(); if (data.Length <= (long)CommonSize.KB512) { body.Add("op", "upload"); body.Add("sha", HexStringFromBytes(sha1.ComputeHash(data))); var wholeFile = GetNextBinary(0, data); - return PostToQCloud(body, wholeFile, cancellationToken).OnSuccess(_ => { - if (_.Result.Item1 == HttpStatusCode.OK) { - done = true; - } - return _.Result; - }); + var result = await PostToQCloud(body, wholeFile, cancellationToken); + if (result.Item1 == HttpStatusCode.OK) { + done = true; + } + return result; } else { body.Add("op", "upload_slice"); body.Add("filesize", data.Length); @@ -101,7 +101,7 @@ namespace LeanCloud.Storage.Internal { body.Add("slice_size", (long)CommonSize.KB512); } - return PostToQCloud(body, null, cancellationToken); + return await PostToQCloud(body, null, cancellationToken); } public static string HexStringFromBytes(byte[] bytes) { var sb = new StringBuilder(); diff --git a/Storage/Storage/Internal/File/Controller/QiniuUploader.cs b/Storage/Storage/Internal/File/Controller/QiniuUploader.cs index 146fc1e..bcfcf50 100644 --- a/Storage/Storage/Internal/File/Controller/QiniuUploader.cs +++ b/Storage/Storage/Internal/File/Controller/QiniuUploader.cs @@ -22,16 +22,15 @@ namespace LeanCloud.Storage.Internal { internal static string UP_HOST = "https://up.qbox.me"; private readonly object mutex = new object(); - public Task Upload(FileState state, Stream dataStream, IDictionary fileToken, IProgress progress, CancellationToken cancellationToken) { + public async Task Upload(FileState state, Stream dataStream, IDictionary fileToken, IProgress progress, CancellationToken cancellationToken) { state.frozenData = dataStream; state.CloudName = fileToken["key"] as string; MergeFromJSON(state, fileToken); - return UploadNextChunk(state, dataStream, string.Empty, 0, progress).OnSuccess(_ => { - return state; - }); + await UploadNextChunk(state, dataStream, string.Empty, 0, progress); + return state; } - Task UploadNextChunk(FileState state, Stream dataStream, string context, long offset, IProgress progress) { + async Task UploadNextChunk(FileState state, Stream dataStream, string context, long offset, IProgress progress) { var totalSize = dataStream.Length; var remainingSize = totalSize - state.completed; @@ -43,29 +42,27 @@ namespace LeanCloud.Storage.Internal { } } if (state.completed == totalSize) { - return QiniuMakeFile(state, state.frozenData, state.token, state.CloudName, totalSize, state.block_ctxes.ToArray(), CancellationToken.None); - } - if (state.completed % BLOCKSIZE == 0) { + await QiniuMakeFile(state, state.frozenData, state.token, state.CloudName, totalSize, state.block_ctxes.ToArray(), CancellationToken.None); + } else if (state.completed % BLOCKSIZE == 0) { var firstChunkBinary = GetChunkBinary(state.completed, dataStream); var blockSize = remainingSize > BLOCKSIZE ? BLOCKSIZE : remainingSize; - return MakeBlock(state, firstChunkBinary, blockSize).OnSuccess(t => { - var dict = t.Result; - var ctx = dict["ctx"].ToString(); - offset = long.Parse(dict["offset"].ToString()); - var host = dict["host"].ToString(); + var result = await MakeBlock(state, firstChunkBinary, blockSize); + var dict = result; + var ctx = dict["ctx"].ToString(); + offset = long.Parse(dict["offset"].ToString()); + var host = dict["host"].ToString(); - state.completed += firstChunkBinary.Length; - if (state.completed % BLOCKSIZE == 0 || state.completed == totalSize) { - state.block_ctxes.Add(ctx); - } + state.completed += firstChunkBinary.Length; + if (state.completed % BLOCKSIZE == 0 || state.completed == totalSize) { + state.block_ctxes.Add(ctx); + } - return UploadNextChunk(state, dataStream, ctx, offset, progress); - }).Unwrap(); - } - var chunkBinary = GetChunkBinary(state.completed, dataStream); - return PutChunk(state, chunkBinary, context, offset).OnSuccess(t => { - var dict = t.Result; + await UploadNextChunk(state, dataStream, ctx, offset, progress); + } else { + var chunkBinary = GetChunkBinary(state.completed, dataStream); + var result = await PutChunk(state, chunkBinary, context, offset); + var dict = result; var ctx = dict["ctx"].ToString(); offset = long.Parse(dict["offset"].ToString()); @@ -74,9 +71,8 @@ namespace LeanCloud.Storage.Internal { if (state.completed % BLOCKSIZE == 0 || state.completed == totalSize) { state.block_ctxes.Add(ctx); } - - return UploadNextChunk(state, dataStream, ctx, offset, progress); - }).Unwrap(); + await UploadNextChunk(state, dataStream, ctx, offset, progress); + } } byte[] GetChunkBinary(long completed, Stream dataStream) { diff --git a/Storage/Storage/Public/AVCloud.cs b/Storage/Storage/Public/AVCloud.cs index 4aa4472..6c6cf3a 100644 --- a/Storage/Storage/Public/AVCloud.cs +++ b/Storage/Storage/Public/AVCloud.cs @@ -220,19 +220,18 @@ namespace LeanCloud { /// captcha image height. /// CancellationToken. /// an instance of Captcha. - public static Task RequestCaptchaAsync(int width = 85, int height = 30, CancellationToken cancellationToken = default) { + public static async Task RequestCaptchaAsync(int width = 85, int height = 30, CancellationToken cancellationToken = default) { var path = string.Format("requestCaptcha?width={0}&height={1}", width, height); var command = new AVCommand { Path = $"requestCaptcha?width={width}&height={height}", Method = HttpMethod.Get }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command, cancellationToken).OnSuccess(t => { - var decoded = AVDecoder.Instance.Decode(t.Result.Item2) as IDictionary; - return new Captcha() { - Token = decoded["captcha_token"] as string, - Url = decoded["captcha_url"] as string, - }; - }); + var result = await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command, cancellationToken); + var decoded = AVDecoder.Instance.Decode(result.Item2) as IDictionary; + return new Captcha { + Token = decoded["captcha_token"] as string, + Url = decoded["captcha_url"] as string, + }; } /// @@ -242,7 +241,7 @@ namespace LeanCloud { /// User's input of this captcha. /// CancellationToken. /// - public static Task VerifyCaptchaAsync(string code, string token, CancellationToken cancellationToken = default) { + public static async Task VerifyCaptchaAsync(string code, string token, CancellationToken cancellationToken = default) { var data = new Dictionary { { "captcha_token", token }, { "captcha_code", code }, @@ -252,11 +251,11 @@ namespace LeanCloud { Method = HttpMethod.Post, Content = data }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command, cancellationToken).ContinueWith(t => { - if (!t.Result.Item2.ContainsKey("validate_token")) - throw new KeyNotFoundException("validate_token"); - return t.Result.Item2["validate_token"] as string; - }); + var result = await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command, cancellationToken); + if (result.Item2.TryGetValue("validate_token", out object tokenObj)) { + return tokenObj as string; + } + throw new KeyNotFoundException("validate_token"); } /// @@ -264,16 +263,15 @@ namespace LeanCloud { /// /// /// - public static Task> GetCustomParametersAsync(CancellationToken cancellationToken = default) { + public static async Task> GetCustomParametersAsync(CancellationToken cancellationToken = default) { var command = new AVCommand { Path = $"statistics/apps/{AVClient.CurrentConfiguration.ApplicationId}/sendPolicy", Method = HttpMethod.Get }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command, cancellationToken).OnSuccess(t => { - var settings = t.Result.Item2; - var CloudParameters = settings["parameters"] as IDictionary; - return CloudParameters; - }); + var data = await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command, cancellationToken); + var settings = data.Item2; + var CloudParameters = settings["parameters"] as IDictionary; + return CloudParameters; } public class RealtimeSignature { @@ -283,7 +281,7 @@ namespace LeanCloud { public string Signature { internal set; get; } } - public static Task RequestRealtimeSignatureAsync(CancellationToken cancellationToken = default) { + public static async Task RequestRealtimeSignatureAsync(CancellationToken cancellationToken = default) { var command = new AVCommand { Path = "rtm/sign", Method = HttpMethod.Post, @@ -291,15 +289,14 @@ namespace LeanCloud { { "session_token", AVUser.CurrentUser?.SessionToken } } }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command, cancellationToken).OnSuccess(t => { - var body = t.Result.Item2; - return new RealtimeSignature() { - Nonce = body["nonce"] as string, - Timestamp = (long)body["timestamp"], - ClientId = body["client_id"] as string, - Signature = body["signature"] as string, - }; - }); + var result = await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command, cancellationToken); + var body = result.Item2; + return new RealtimeSignature() { + Nonce = body["nonce"] as string, + Timestamp = (long)body["timestamp"], + ClientId = body["client_id"] as string, + Signature = body["signature"] as string, + }; } /// diff --git a/Storage/Storage/Public/AVFile.cs b/Storage/Storage/Public/AVFile.cs index d41d7b9..1d1d7d9 100644 --- a/Storage/Storage/Public/AVFile.cs +++ b/Storage/Storage/Public/AVFile.cs @@ -265,11 +265,8 @@ namespace LeanCloud { /// /// The progress callback. /// The cancellation token. - public Task SaveAsync(IProgress progress = null, CancellationToken cancellationToken = default) { - return FileController.SaveAsync(state, dataStream, progress, cancellationToken) - .OnSuccess(t => { - state = t.Result; - }); + public async Task SaveAsync(IProgress progress = null, CancellationToken cancellationToken = default) { + state = await FileController.SaveAsync(state, dataStream, progress, cancellationToken); } #endregion @@ -320,11 +317,9 @@ namespace LeanCloud { /// /// 获取之后并没有实际执行下载,只是加载了文件的元信息以及物理地址(Url) /// - public static Task GetFileWithObjectIdAsync(string objectId, CancellationToken cancellationToken = default) { - return FileController.GetAsync(objectId, cancellationToken).OnSuccess(_ => { - var filestate = _.Result; - return new AVFile(filestate); - }); + public static async Task GetFileWithObjectIdAsync(string objectId, CancellationToken cancellationToken = default) { + var fileState = await FileController.GetAsync(objectId, cancellationToken); + return new AVFile(fileState); } public static AVFile CreateWithoutData(string objectId) { diff --git a/Storage/Storage/Public/AVQuery.cs b/Storage/Storage/Public/AVQuery.cs index fdf9055..d696e52 100644 --- a/Storage/Storage/Public/AVQuery.cs +++ b/Storage/Storage/Public/AVQuery.cs @@ -10,8 +10,7 @@ using System.Text.RegularExpressions; using Newtonsoft.Json; using LeanCloud.Storage.Internal; -namespace LeanCloud -{ +namespace LeanCloud { public class AVQuery where T : AVObject { public string ClassName { get; internal set; @@ -24,7 +23,8 @@ namespace LeanCloud return $"classes/{Uri.EscapeDataString(ClassName)}"; } return path; - } set { + } + set { path = value; } } @@ -202,56 +202,41 @@ namespace LeanCloud }); } - public Task> FindAsync(CancellationToken cancellationToken = default) - { - return QueryController.FindAsync(this, AVUser.CurrentUser, cancellationToken).OnSuccess(t => { - IEnumerable states = t.Result; - return (from state in states - select AVObject.FromState(state, ClassName)); - }); + public async Task> FindAsync(CancellationToken cancellationToken = default) { + IEnumerable states = await QueryController.FindAsync(this, AVUser.CurrentUser, cancellationToken); + return (from state in states + select AVObject.FromState(state, ClassName)); } - public Task FirstOrDefaultAsync(CancellationToken cancellationToken = default) - { - return QueryController.FirstAsync(this, AVUser.CurrentUser, cancellationToken).OnSuccess(t => { - IObjectState state = t.Result; - return state == null ? default : AVObject.FromState(state, ClassName); - }); + public async Task FirstOrDefaultAsync(CancellationToken cancellationToken = default) { + IObjectState state = await QueryController.FirstAsync(this, AVUser.CurrentUser, cancellationToken); + return state == null ? default : AVObject.FromState(state, ClassName); } - public Task FirstAsync(CancellationToken cancellationToken = default) - { - return FirstOrDefaultAsync(cancellationToken).OnSuccess(t => - { - if (t.Result == null) - { - throw new AVException(AVException.ErrorCode.ObjectNotFound, - "No results matched the query."); - } - return t.Result; - }); + public async Task FirstAsync(CancellationToken cancellationToken = default) { + var result = await FirstOrDefaultAsync(cancellationToken); + if (result == null) { + throw new AVException(AVException.ErrorCode.ObjectNotFound, + "No results matched the query."); + } + return result; } - public Task CountAsync(CancellationToken cancellationToken = default) - { + public Task CountAsync(CancellationToken cancellationToken = default) { return QueryController.CountAsync(this, AVUser.CurrentUser, cancellationToken); } - public Task GetAsync(string objectId, CancellationToken cancellationToken) - { + public async Task GetAsync(string objectId, CancellationToken cancellationToken) { AVQuery singleItemQuery = new AVQuery(ClassName) .WhereEqualTo("objectId", objectId); singleItemQuery = new AVQuery(singleItemQuery, includes: this.includes, selectedKeys: this.selectedKeys, limit: 1); - return singleItemQuery.FindAsync(cancellationToken).OnSuccess(t => - { - var result = t.Result.FirstOrDefault(); - if (result == null) - { - throw new AVException(AVException.ErrorCode.ObjectNotFound, - "Object with the given objectId not found."); - } - return result; - }); + var result = await singleItemQuery.FindAsync(cancellationToken); + var first = result.FirstOrDefault(); + if (first == null) { + throw new AVException(AVException.ErrorCode.ObjectNotFound, + "Object with the given objectId not found."); + } + return first; } #region CQL @@ -289,22 +274,20 @@ namespace LeanCloud return RebuildObjectFromCloudQueryResult(queryString); } - internal static Task> RebuildObjectFromCloudQueryResult(string queryString) { + internal static async Task> RebuildObjectFromCloudQueryResult(string queryString) { var command = new AVCommand { Path = queryString, Method = HttpMethod.Get }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command, cancellationToken: CancellationToken.None).OnSuccess(t => - { - var items = t.Result.Item2["results"] as IList; - var className = t.Result.Item2["className"].ToString(); + var result = await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command, CancellationToken.None); + var items = result.Item2["results"] as IList; + var className = result.Item2["className"].ToString(); - IEnumerable states = (from item in items - select AVObjectCoder.Instance.Decode(item as IDictionary, AVDecoder.Instance)); + IEnumerable states = (from item in items + select AVObjectCoder.Instance.Decode(item as IDictionary, AVDecoder.Instance)); - return (from state in states - select AVObject.FromState(state, className)); - }); + return from state in states + select AVObject.FromState(state, className); } #endregion diff --git a/Storage/Storage/Public/LeaderBoard/AVLeaderboard.cs b/Storage/Storage/Public/LeaderBoard/AVLeaderboard.cs index 4cf582c..3537846 100644 --- a/Storage/Storage/Public/LeaderBoard/AVLeaderboard.cs +++ b/Storage/Storage/Public/LeaderBoard/AVLeaderboard.cs @@ -138,7 +138,7 @@ namespace LeanCloud { /// 排序方式 /// 版本更新频率 /// 成绩更新策略 - public static Task CreateLeaderboard(string statisticName, + public static async Task CreateLeaderboard(string statisticName, AVLeaderboardOrder order = AVLeaderboardOrder.DESCENDING, AVLeaderboardUpdateStrategy updateStrategy = AVLeaderboardUpdateStrategy.BETTER, AVLeaderboardVersionChangeInterval versionChangeInterval = AVLeaderboardVersionChangeInterval.WEEK) { @@ -157,14 +157,13 @@ namespace LeanCloud { Method = HttpMethod.Post, Content = data }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command).OnSuccess(t => { - try { - var leaderboard = Parse(t.Result.Item2); - return leaderboard; - } catch (Exception e) { - throw new AVException(AVException.ErrorCode.InvalidJSON, e.Message); - } - }); + var result = await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command); + try { + var leaderboard = Parse(result.Item2); + return leaderboard; + } catch (Exception e) { + throw new AVException(AVException.ErrorCode.InvalidJSON, e.Message); + } } /// @@ -195,7 +194,7 @@ namespace LeanCloud { /// 用户 /// 成绩 /// 是否强行覆盖 - public static Task> UpdateStatistics(AVUser user, Dictionary statistics, bool overwrite = false) { + public static async Task> UpdateStatistics(AVUser user, Dictionary statistics, bool overwrite = false) { if (user == null) { throw new ArgumentNullException(nameof(user)); } @@ -219,18 +218,17 @@ namespace LeanCloud { Method = HttpMethod.Post, Content = data }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command).OnSuccess(t => { - try { - List statisticList = new List(); - List list = t.Result.Item2["results"] as List; - foreach (object obj in list) { - statisticList.Add(AVStatistic.Parse(obj as IDictionary)); - } - return statisticList; - } catch (Exception e) { - throw new AVException(AVException.ErrorCode.InvalidJSON, e.Message); + var result = await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command); + try { + List statisticList = new List(); + List list = result.Item2["results"] as List; + foreach (object obj in list) { + statisticList.Add(AVStatistic.Parse(obj as IDictionary)); } - }); + return statisticList; + } catch (Exception e) { + throw new AVException(AVException.ErrorCode.InvalidJSON, e.Message); + } } /// @@ -239,7 +237,7 @@ namespace LeanCloud { /// 成绩列表 /// 用户 /// 名称列表 - public static Task> GetStatistics(AVUser user, List statisticNames = null) { + public static async Task> GetStatistics(AVUser user, List statisticNames = null) { if (user == null) { throw new ArgumentNullException(nameof(user)); } @@ -252,18 +250,17 @@ namespace LeanCloud { Path = path, Method = HttpMethod.Post }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command).OnSuccess(t => { - try { - List statisticList = new List(); - List list = t.Result.Item2["results"] as List; - foreach (object obj in list) { - statisticList.Add(AVStatistic.Parse(obj as IDictionary)); - } - return statisticList; - } catch (Exception e) { - throw new AVException(AVException.ErrorCode.InvalidJSON, e.Message); + var result = await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command); + try { + List statisticList = new List(); + List list = result.Item2["results"] as List; + foreach (object obj in list) { + statisticList.Add(AVStatistic.Parse(obj as IDictionary)); } - }); + return statisticList; + } catch (Exception e) { + throw new AVException(AVException.ErrorCode.InvalidJSON, e.Message); + } } /// @@ -271,7 +268,7 @@ namespace LeanCloud { /// /// 用户 /// 名称列表 - public static Task DeleteStatistics(AVUser user, List statisticNames) { + public static async Task DeleteStatistics(AVUser user, List statisticNames) { if (user == null) { throw new ArgumentNullException(nameof(user)); } @@ -285,7 +282,7 @@ namespace LeanCloud { Path = path, Method = HttpMethod.Delete, }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command); + await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command); } /// @@ -294,21 +291,20 @@ namespace LeanCloud { /// 排行榜归档列表 /// 跳过数量 /// 分页数量 - public Task> GetArchives(int skip = 0, int limit = 10) { + public async Task> GetArchives(int skip = 0, int limit = 10) { var path = string.Format("leaderboard/leaderboards/{0}/archives", StatisticName); path = string.Format("{0}?skip={1}&limit={2}", path, skip, limit); var command = new AVCommand { Path = path, Method = HttpMethod.Get }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command).OnSuccess(t => { - List archives = new List(); - List list = t.Result.Item2["results"] as List; - foreach (object obj in list) { - archives.Add(AVLeaderboardArchive.Parse(obj as IDictionary)); - } - return archives; - }); + var result = await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command); + List archives = new List(); + List list = result.Item2["results"] as List; + foreach (object obj in list) { + archives.Add(AVLeaderboardArchive.Parse(obj as IDictionary)); + } + return archives; } /// @@ -336,7 +332,7 @@ namespace LeanCloud { return GetResults(AVUser.CurrentUser, version, skip, limit, selectUserKeys, includeStatistics); } - Task> GetResults(AVUser user, + async Task> GetResults(AVUser user, int version, int skip, int limit, List selectUserKeys, List includeStatistics) { @@ -361,18 +357,17 @@ namespace LeanCloud { Path = path, Method = HttpMethod.Get }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command).OnSuccess(t => { - try { - List rankingList = new List(); - List list = t.Result.Item2["results"] as List; - foreach (object obj in list) { - rankingList.Add(AVRanking.Parse(obj as IDictionary)); - } - return rankingList; - } catch (Exception e) { - throw new AVException(AVException.ErrorCode.InvalidJSON, e.Message); + var result = await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command); + try { + List rankingList = new List(); + List list = result.Item2["results"] as List; + foreach (object obj in list) { + rankingList.Add(AVRanking.Parse(obj as IDictionary)); } - }); + return rankingList; + } catch (Exception e) { + throw new AVException(AVException.ErrorCode.InvalidJSON, e.Message); + } } /// @@ -380,14 +375,13 @@ namespace LeanCloud { /// /// 排行榜对象 /// 更新策略 - public Task UpdateUpdateStrategy(AVLeaderboardUpdateStrategy updateStrategy) { + public async Task UpdateUpdateStrategy(AVLeaderboardUpdateStrategy updateStrategy) { var data = new Dictionary { { "updateStrategy", updateStrategy.ToString().ToLower() } }; - return Update(data).OnSuccess(t => { - UpdateStrategy = (AVLeaderboardUpdateStrategy)Enum.Parse(typeof(AVLeaderboardUpdateStrategy), t.Result["updateStrategy"].ToString().ToUpper()); - return this; - }); + var result = await Update(data); + UpdateStrategy = (AVLeaderboardUpdateStrategy)Enum.Parse(typeof(AVLeaderboardUpdateStrategy), result["updateStrategy"].ToString().ToUpper()); + return this; } /// @@ -395,67 +389,63 @@ namespace LeanCloud { /// /// 排行榜对象 /// 版本更新频率 - public Task UpdateVersionChangeInterval(AVLeaderboardVersionChangeInterval versionChangeInterval) { + public async Task UpdateVersionChangeInterval(AVLeaderboardVersionChangeInterval versionChangeInterval) { var data = new Dictionary { { "versionChangeInterval", versionChangeInterval.ToString().ToLower() } }; - return Update(data).OnSuccess(t => { - VersionChangeInterval = (AVLeaderboardVersionChangeInterval)Enum.Parse(typeof(AVLeaderboardVersionChangeInterval), t.Result["versionChangeInterval"].ToString().ToUpper()); - return this; - }); + var result = await Update(data); + VersionChangeInterval = (AVLeaderboardVersionChangeInterval)Enum.Parse(typeof(AVLeaderboardVersionChangeInterval), result["versionChangeInterval"].ToString().ToUpper()); + return this; } - Task> Update(Dictionary data) { + async Task> Update(Dictionary data) { var path = string.Format("leaderboard/leaderboards/{0}", StatisticName); var command = new AVCommand { Path = path, Method = HttpMethod.Put, Content = data }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command).OnSuccess(t => { - return t.Result.Item2; - }); + var result = await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command); + return result.Item2; } /// /// 拉取排行榜数据 /// /// 排行榜对象 - public Task Fetch() { + public async Task Fetch() { var path = string.Format("leaderboard/leaderboards/{0}", StatisticName); var command = new AVCommand { Path = path, Method = HttpMethod.Get }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command).OnSuccess(t => { - try { - // 反序列化 Leaderboard 对象 - var leaderboard = Parse(t.Result.Item2); - return leaderboard; - } catch (Exception e) { - throw new AVException(AVException.ErrorCode.InvalidJSON, e.Message); - } - }); + var result = await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command); + try { + // 反序列化 Leaderboard 对象 + var leaderboard = Parse(result.Item2); + return leaderboard; + } catch (Exception e) { + throw new AVException(AVException.ErrorCode.InvalidJSON, e.Message); + } } /// /// 重置排行榜 /// /// 排行榜对象 - public Task Reset() { + public async Task Reset() { var path = string.Format("leaderboard/leaderboards/{0}/incrementVersion", StatisticName); var command = new AVCommand { Path = path, Method = HttpMethod.Put }; - return AVPlugins.Instance.CommandRunner.RunCommandAsync>(command).OnSuccess(t => { - try { - Init(t.Result.Item2); - return this; - } catch (Exception e) { - throw new AVException(AVException.ErrorCode.InvalidJSON, e.Message); - } - }); + var result = await AVPlugins.Instance.CommandRunner.RunCommandAsync>(command); + try { + Init(result.Item2); + return this; + } catch (Exception e) { + throw new AVException(AVException.ErrorCode.InvalidJSON, e.Message); + } } ///