Created
December 22, 2012 03:12
-
-
Save coldacid/4357319 to your computer and use it in GitHub Desktop.
Using the `async`/`await` keywords in C# makes it a lot easier to write asychronous code, which is very important for people working with Windows Phone or Windows 8. These keywords work with the Task Asynchronous Pattern (TAP) which is built around the `System.Threading.Tasks.Task` class, and which has an adaptor, `TaskCompletionSource<>`, for d…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using Scoreloop.CoreSocial.API; | |
using Scoreloop.CoreSocial.API.Model; | |
using System.Threading.Tasks; | |
using ScoreloopGame = Scoreloop.CoreSocial.API.Model.Game; | |
namespace Taptics | |
{ | |
static class ScoreloopAsyncHelper | |
{ | |
#region IRequestController handler management | |
private static bool IsInstanceOfGenericType(this Type @this, object o) | |
{ | |
Type type = o.GetType(); | |
while (type != null) | |
{ | |
if (type.IsGenericType && type.GetGenericTypeDefinition() == @this) | |
return true; | |
type = type.BaseType; | |
} | |
return false; | |
} | |
private static Action SetupRequestHandlers(IRequestController controller, object taskCompletionSource, Action callbackRemoval = null) | |
{ | |
var tcsType = typeof(TaskCompletionSource<>); | |
if (!tcsType.IsInstanceOfGenericType(taskCompletionSource)) | |
throw new ArgumentException("taskCompletionSource must be of TaskCompletionSource<>"); | |
var mTrySetException = tcsType.GetMethod("TrySetException", new Type[] { typeof(Exception) }); | |
var mTrySetCancelled = tcsType.GetMethod("TrySetCancelled"); | |
EventHandler<RequestControllerEventArgs<IRequestController>> requestFailedHandler = null; | |
EventHandler<RequestControllerEventArgs<IRequestController>> requestCancelledHandler = null; | |
Action removeHandlers = () => | |
{ | |
RemoveRequestHandlers(controller, requestFailedHandler, requestCancelledHandler); | |
if (callbackRemoval != null) | |
callbackRemoval(); | |
}; | |
requestFailedHandler = (s, e) => | |
{ | |
removeHandlers(); | |
mTrySetException.Invoke(taskCompletionSource, new[] { e.Error.Exception }); | |
}; | |
requestCancelledHandler = (s, e) => | |
{ | |
removeHandlers(); | |
mTrySetCancelled.Invoke(taskCompletionSource, null); | |
}; | |
controller.RequestFailed += requestFailedHandler; | |
controller.RequestCancelled += requestCancelledHandler; | |
return removeHandlers; | |
} | |
private static void RemoveRequestHandlers(IRequestController controller, EventHandler<RequestControllerEventArgs<IRequestController>> requestFailedHandler, EventHandler<RequestControllerEventArgs<IRequestController>> requestCancelledHandler) | |
{ | |
controller.RequestFailed -= requestFailedHandler; | |
controller.RequestCancelled -= requestCancelledHandler; | |
} | |
#endregion | |
#region IScoresController.LoadScores | |
private static TaskCompletionSource<Score[]> ScoresControllerLoadScoresAsyncSetup(IScoresController controller) | |
{ | |
var tcs = new TaskCompletionSource<Score[]>(); | |
EventHandler<RequestControllerEventArgs<IScoresController>> scoresLoadedHandler = null; | |
var removeHandlers = SetupRequestHandlers(controller, tcs, () => { controller.ScoresLoaded -= scoresLoadedHandler; }); | |
scoresLoadedHandler = (s, e) => | |
{ | |
removeHandlers(); | |
tcs.TrySetResult(controller.Scores); | |
}; | |
controller.ScoresLoaded += scoresLoadedHandler; | |
return tcs; | |
} | |
public static Task<Score[]> LoadScoresAsync(this IScoresController @this, ScoreSearchList list, Range range, int mode = 0, ScoreloopGame game = null) | |
{ | |
var tcs = ScoresControllerLoadScoresAsyncSetup(@this); | |
if (game == null) | |
game = @this.Game; | |
@this.LoadScores(list, range, mode, game); | |
return tcs.Task; | |
} | |
public static Task<Score[]> LoadScoresAsync(this IScoresController @this, ScoreSearchList list, Range range, Score scoreToInject, ScoreloopGame game = null) | |
{ | |
var tcs = ScoresControllerLoadScoresAsyncSetup(@this); | |
if (game == null) | |
game = @this.Game; | |
@this.LoadScores(list, range, scoreToInject, game); | |
return tcs.Task; | |
} | |
public static Task<Score[]> LoadScoresAsync(this IScoresController @this, ScoreSearchList list, Score score, int limit, ScoreloopGame game = null) | |
{ | |
var tcs = ScoresControllerLoadScoresAsyncSetup(@this); | |
if (game == null) | |
game = @this.Game; | |
@this.LoadScores(list, score, limit, game); | |
return tcs.Task; | |
} | |
public static Task<Score[]> LoadScoresAsync(this IScoresController @this, ScoreSearchList list, ulong rank, int limit, int mode = 0, ScoreloopGame game = null) | |
{ | |
var tcs = ScoresControllerLoadScoresAsyncSetup(@this); | |
if (game == null) | |
game = @this.Game; | |
@this.LoadScores(list, rank, limit, mode, game); | |
return tcs.Task; | |
} | |
public static Task<Score[]> LoadScoresAsync(this IScoresController @this, ScoreSearchList list, User user, int limit, int mode = 0, ScoreloopGame game = null) | |
{ | |
var tcs = ScoresControllerLoadScoresAsyncSetup(@this); | |
if (game == null) | |
game = @this.Game; | |
@this.LoadScores(list, user, limit, mode, game); | |
return tcs.Task; | |
} | |
#endregion | |
#region IScoreController.Submit | |
public static Task SubmitAsync(this IScoreController @this, Score score) | |
{ | |
var tcs = new TaskCompletionSource<object>(); | |
EventHandler<RequestControllerEventArgs<IScoreController>> scoreSubmittedHandler = null; | |
var removeHandlers = SetupRequestHandlers(@this, tcs, () => { @this.ScoreSubmitted -= scoreSubmittedHandler; }); | |
scoreSubmittedHandler = (s, e) => | |
{ | |
removeHandlers(); | |
tcs.TrySetResult(null); | |
}; | |
@this.ScoreSubmitted += scoreSubmittedHandler; | |
@this.Submit(score); | |
return tcs.Task; | |
} | |
#endregion | |
#region IUserController.Load | |
private static TaskCompletionSource<User> UserControllerLoadAsyncSetup(IUserController controller) | |
{ | |
var tcs = new TaskCompletionSource<User>(); | |
EventHandler<RequestControllerEventArgs<IUserController>> userLoadedHandler = null; | |
var removeHandlers = SetupRequestHandlers(controller, tcs, () => { controller.UserLoaded -= userLoadedHandler; }); | |
userLoadedHandler = (s, e) => | |
{ | |
removeHandlers(); | |
tcs.TrySetResult(controller.User); | |
}; | |
controller.UserLoaded += userLoadedHandler; | |
return tcs; | |
} | |
public static Task<User> LoadAsync(this IUserController @this, UserLoadScope scope) | |
{ | |
var tcs = UserControllerLoadAsyncSetup(@this); | |
@this.Load(scope); | |
return tcs.Task; | |
} | |
public static Task<User> LoadAsync(this IUserController @this, Activity activity, UserLoadScope scope) | |
{ | |
var tcs = UserControllerLoadAsyncSetup(@this); | |
@this.Load(activity, scope); | |
return tcs.Task; | |
} | |
public static Task<User> LoadAsync(this IUserController @this, User user, UserLoadScope scope) | |
{ | |
var tcs = UserControllerLoadAsyncSetup(@this); | |
@this.Load(user, scope); | |
return tcs.Task; | |
} | |
#endregion | |
#region IUserController.Update | |
private static TaskCompletionSource<object> UserControllerUpdateAsyncSetup(IUserController controller) | |
{ | |
var tcs = new TaskCompletionSource<object>(); | |
EventHandler<RequestControllerEventArgs<IUserController>> userUpdatedHandler = null; | |
var removeHandlers = SetupRequestHandlers(controller, tcs, () => { controller.UserUpdated -= userUpdatedHandler; }); | |
userUpdatedHandler = (s, e) => | |
{ | |
removeHandlers(); | |
tcs.TrySetResult(null); | |
}; | |
controller.UserUpdated += userUpdatedHandler; | |
return tcs; | |
} | |
public static Task UpdateAsync(this IUserController @this, string login, string email) | |
{ | |
var tcs = UserControllerUpdateAsyncSetup(@this); | |
@this.Update(login, email); | |
return tcs.Task; | |
} | |
public static Task UpdateAsync(this IUserController @this, Context context) | |
{ | |
var tcs = UserControllerUpdateAsyncSetup(@this); | |
@this.Update(context); | |
return tcs.Task; | |
} | |
public static Task UpdateAsync(this IUserController @this, DateTime birthDate) | |
{ | |
var tcs = UserControllerUpdateAsyncSetup(@this); | |
@this.Update(birthDate); | |
return tcs.Task; | |
} | |
public static Task UpdateAsync(this IUserController @this, string nationality) | |
{ | |
var tcs = UserControllerUpdateAsyncSetup(@this); | |
@this.Update(nationality); | |
return tcs.Task; | |
} | |
public static Task UpdateAsync(this IUserController @this, User user, Context context) | |
{ | |
var tcs = UserControllerUpdateAsyncSetup(@this); | |
@this.Update(user, context); | |
return tcs.Task; | |
} | |
public static Task UpdateAsync(this IUserController @this, string login, string email, DateTime birthDate) | |
{ | |
var tcs = UserControllerUpdateAsyncSetup(@this); | |
@this.Update(login, email, birthDate); | |
return tcs.Task; | |
} | |
public static Task UpdateAsync(this IUserController @this, string login, string email, string nationality, DateTime birthDate) | |
{ | |
var tcs = UserControllerUpdateAsyncSetup(@this); | |
@this.Update(login, email, nationality, birthDate); | |
return tcs.Task; | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment