Skip to content

Instantly share code, notes, and snippets.

@shadeglare
Last active December 21, 2015 04:39
Show Gist options
  • Save shadeglare/6250970 to your computer and use it in GitHub Desktop.
Save shadeglare/6250970 to your computer and use it in GitHub Desktop.
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