Last active
December 21, 2015 04:39
-
-
Save shadeglare/6250970 to your computer and use it in GitHub Desktop.
This file contains hidden or 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.Threading; | |
using System.Threading.Tasks; | |
using System.Diagnostics; | |
public sealed class DistributorOperationInfo | |
{ | |
public Object NativeRequest { get; set; } | |
public Object NativeResponse { get; set; } | |
public String Error { get; set; } | |
public String Name { get; set; } | |
} | |
public abstract class DistributorClientWrapper<TDistributorClient, TCredential> | |
{ | |
public TDistributorClient Client { get; protected set; } | |
public TCredential Credential { get; protected set; } | |
public DistributorClientWrapper() | |
{ | |
InitializeDistributorClient(); | |
} | |
protected abstract void InitializeDistributorClient(); | |
public async Task<TResponse> ExecuteOperationAsync<TRequest, TResponse>( | |
Func<TCredential, TRequest, Task<TResponse>> operation, | |
TRequest request) | |
{ | |
var result = default(TResponse); | |
var error = default(String); | |
try | |
{ | |
result = await operation(Credential, request); | |
} | |
catch (Exception e) | |
{ | |
error = e.ToString(); | |
throw; | |
} | |
finally | |
{ | |
OnOperationComplete(new DistributorOperationInfo | |
{ | |
Error = error, | |
NativeRequest = request, | |
NativeResponse = result, | |
Name = operation.Method.Name, | |
}); | |
} | |
return result; | |
} | |
public async Task<TResponse> ExecuteOperationAsync<TRequest, TResponse, TParam>( | |
Func<TCredential, TRequest, TParam, Task<TResponse>> operation, | |
TRequest request, TParam param) | |
{ | |
var result = default(TResponse); | |
var error = default(String); | |
try | |
{ | |
result = await operation(Credential, request, param); | |
} | |
catch (Exception e) | |
{ | |
error = e.ToString(); | |
throw; | |
} | |
finally | |
{ | |
OnOperationComplete(new DistributorOperationInfo | |
{ | |
Error = error, | |
NativeRequest = request, | |
NativeResponse = result, | |
Name = operation.Method.Name, | |
}); | |
} | |
return result; | |
} | |
public async Task<TResponse> ExecuteOperationAsync<TRequest, TResponse>( | |
Func<TRequest, Task<TResponse>> operation, | |
TRequest request) | |
{ | |
var result = default(TResponse); | |
var error = default(String); | |
try | |
{ | |
result = await operation(request); | |
} | |
catch (Exception e) | |
{ | |
error = e.ToString(); | |
throw; | |
} | |
finally | |
{ | |
OnOperationComplete(new DistributorOperationInfo | |
{ | |
Error = error, | |
NativeRequest = request, | |
NativeResponse = result, | |
Name = operation.Method.Name, | |
}); | |
} | |
return result; | |
} | |
public async Task<TResponse> ExecuteOperationAsync<TRequest, TResponse, TParam>( | |
Func<TRequest, TParam, Task<TResponse>> operation, | |
TRequest request, TParam param) | |
{ | |
var result = default(TResponse); | |
var error = default(String); | |
try | |
{ | |
result = await operation(request, param); | |
} | |
catch (Exception e) | |
{ | |
error = e.ToString(); | |
throw; | |
} | |
finally | |
{ | |
OnOperationComplete(new DistributorOperationInfo | |
{ | |
Error = error, | |
NativeRequest = request, | |
NativeResponse = result, | |
Name = operation.Method.Name, | |
}); | |
} | |
return result; | |
} | |
public event Action<DistributorOperationInfo> OperationComplete = (o) => { }; | |
protected virtual void OnOperationComplete(DistributorOperationInfo operationInfo) | |
{ | |
OperationComplete(operationInfo); | |
} | |
} | |
// Mock native client credential | |
public sealed class NativeClientCredential | |
{ | |
public String Key { get; set; } | |
} | |
// Mock native client | |
public sealed class NativeClient | |
{ | |
//Emulates long task. | |
public async Task<Int32> CalculateFactorialAsync(NativeClientCredential credential, Int32 number) | |
{ | |
CheckCredential(credential); | |
var task = Task.Factory.StartNew<Int32>(() => | |
{ | |
Thread.Sleep(20); | |
var result = 1; | |
if (number >= 22) | |
{ | |
throw new ArgumentException(); | |
} | |
if (number != 0 && number != 1) | |
{ | |
for (var i = 2; i <= number; i++) | |
{ | |
result *= i; | |
} | |
} | |
return result; | |
}); | |
return await task; | |
} | |
public Int32 CalculateFactorial(NativeClientCredential credential, Int32 number) | |
{ | |
CheckCredential(credential); | |
Thread.Sleep(20); | |
var result = 1; | |
if (number >= 22) | |
{ | |
throw new ArgumentException(); | |
} | |
if (number != 0 && number != 1) | |
{ | |
for (var i = 2; i <= number; i++) | |
{ | |
result *= i; | |
} | |
} | |
return result; | |
} | |
public Int32 CalculateSum(NativeClientCredential credential, Int32 a, Int32 b) | |
{ | |
CheckCredential(credential); | |
return a + b; | |
} | |
private void CheckCredential(NativeClientCredential credential) | |
{ | |
if (credential.Key != "test") | |
{ | |
throw new InvalidOperationException(); | |
} | |
} | |
} | |
// Mock native client wrapper | |
public sealed class NativeClientWrapper : DistributorClientWrapper<NativeClient, NativeClientCredential> | |
{ | |
protected override void InitializeDistributorClient() | |
{ | |
Credential = new NativeClientCredential { Key = "test" }; | |
Client = new NativeClient(); | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var clientWrapper = new NativeClientWrapper(); | |
clientWrapper.OperationComplete += OperationCompleteCallback; | |
var stopwatch = new Stopwatch(); | |
stopwatch.Start(); | |
for (var i = 0; i < 1000; i++) | |
{ | |
var task = clientWrapper.ExecuteOperationAsync(clientWrapper.Client.CalculateFactorialAsync, 5); | |
var result = task.Result; | |
} | |
stopwatch.Stop(); | |
Console.WriteLine(stopwatch.ElapsedMilliseconds); | |
} | |
public static void OperationCompleteCallback(DistributorOperationInfo operationInfo) | |
{ | |
//My be a logging operations. | |
//Console.WriteLine(operationInfo.ToJson()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment