泛型静态类 & function作为参数

    /// <summary>
///
/// </summary>
/// <typeparam name="OD">original datas type:get from proxy api</typeparam>
/// <typeparam name="SD">save datas type</typeparam>
public static class ReportOperation<OD,SD> where OD : class where SD : class
{
static int _syncCallApiMaxNum= ConfigHelper.SyncCallApiMaxNum;
static int _MaxSaveDataNum = ConfigHelper.MaxSaveDataNum;
static string OriginalDatasType = typeof(OD).FullName;
static string SaveDatasType = typeof(SD).FullName; private static bool TaskSplitForSave(List<ReportSaveTask<SD>> taskList, ILogBase _logger)
{
bool saveResult = true;
try
{
_logger.Info($"TaskSplitForSave.SaveDatasType:{SaveDatasType};");
if (taskList == null || taskList.Count() == 0)
{
return false;
}
int index = 0;
int sumNum = taskList.Count();
int syncCallApiNum = sumNum > 0 ? _syncCallApiMaxNum : sumNum;
while (index < sumNum)
{
List<ReportSaveTask<SD>> temp = new List<ReportSaveTask<SD>>();
syncCallApiNum = syncCallApiNum > sumNum - index ? sumNum - index : syncCallApiNum;
temp = taskList.GetRange(index, syncCallApiNum);
index = index + syncCallApiNum;
System.Threading.Thread.Sleep(5000);
foreach (var oneT in temp)
{
_logger.Info($"start save Report datas to database. start:{index},num:{syncCallApiNum},request:{JsonConvert.SerializeObject(oneT.Data)}");
oneT.SaveResult.Start();
}
Task.WaitAll(temp.Select(each => each.SaveResult).ToArray());
foreach (var teskOne in temp)
{
var saveTempResult = teskOne.SaveResult.Result;
saveResult = saveResult && saveTempResult; if (!saveTempResult)
{
_logger.Warn($"failed to async Report datas to database!,request:{JsonConvert.SerializeObject(teskOne.Data)}");
}
else
{
_logger.Info($"report datas to DB successed!,request:{JsonConvert.SerializeObject(teskOne.Data)}");
}
}
}
_logger.Info($"TaskSplitForSave result:{JsonConvert.SerializeObject(saveResult)};");
return saveResult;
}
catch (Exception ex)
{
_logger.Error($"ProxyReportCallSplit:{ex.ToString()}");
throw ex;
}
} private static List<ReportSaveTask<SD>> DataSplitForSave(List<SD> reportDB,Func<List<SD>,bool> saveOperate, ILogBase _logger)
{ List<ReportSaveTask<SD>> taskList = new List<ReportSaveTask<SD>>();
try
{
_logger.Info($"DataSplitForSave request.reportDB:{JsonConvert.SerializeObject(reportDB)};");
if (reportDB == null || reportDB.Count() == 0)
{
return null;
} int index = 0;
int sumNum = reportDB.Count();
int eachInsert = sumNum > 0 ? _MaxSaveDataNum : sumNum;
while (index < sumNum)
{
List<SD> temp = new List<SD>();
eachInsert = eachInsert > sumNum - index ? sumNum - index : eachInsert;
temp = reportDB.GetRange(index, eachInsert);
index = index + eachInsert;
var taskTemp = new Task<bool>(()=>saveOperate(temp));//_FacebookReportClient.Save(temp)
taskList.Add(new ReportSaveTask<SD>() { SaveResult = taskTemp, Data = temp });
}
return taskList;
}
catch (Exception ex)
{
_logger.Error($"save datas to DB error:{ex.ToString()},request:{JsonConvert.SerializeObject(reportDB)}");
throw ex;
}
} public static bool ProxyApiSplitToCall(List<Task<List<OD>>> taskList,Func<List<OD>,List<SD>> DateConvertToDB, Func<List<SD>,bool> saveOperate, ILogBase _logger)
{
bool result = true;
try
{
_logger.Info($"ProxyApiSplitToCall");
if (taskList == null || taskList.Count() == 0)
{
return false;
}
int index = 0;
int sumNum = taskList.Count();
int syncCallApiNum = sumNum > 0 ? _syncCallApiMaxNum : sumNum;
while (index < sumNum)
{
syncCallApiNum = syncCallApiNum > sumNum - index ? sumNum - index : syncCallApiNum;
List<Task<List<OD>>> temp = taskList.GetRange(index, syncCallApiNum);
index = index + syncCallApiNum; System.Threading.Thread.Sleep(5000);
foreach (var oneT in temp)
{
oneT.Start();
}
Task.WaitAll(temp.ToArray()); #region save data
List<OD> allReports = new List<OD>();
CommandHelper.UnionAllTaskResult<OD>(temp, ref allReports);
if (allReports == null || allReports.Count() == 0)
{
_logger.Warn($"no datas can get from proxy call![{JsonConvert.SerializeObject(allReports)}]");
continue;
}
_logger.Info($"datas get from proxy call:{JsonConvert.SerializeObject(allReports)}");
List<SD> reportDB = DateConvertToDB(allReports);
if (reportDB == null || reportDB.Count() == 0)
{
_logger.Warn($"no datas need to be created or updated:{JsonConvert.SerializeObject(reportDB)}");
continue;
}
_logger.Info($"datas need to be save :{JsonConvert.SerializeObject(reportDB)}");
List<ReportSaveTask<SD>> DataSaveT= DataSplitForSave(reportDB, saveOperate, _logger);
bool saveResult = TaskSplitForSave(DataSaveT, _logger);
_logger.Info($"datas save result:{JsonConvert.SerializeObject(saveResult)}");
#endregion result = result & saveResult;
}
return result;
}
catch (Exception ex)
{
_logger.Error($"ProxyReportCallSplit:{ex.ToString()}");
throw ex;
}
}
}

  

静态类的使用

bool saveResult = ReportOperation<FacebookDailyReportConvertFromClient, FacebookImpressDeviceReport>.ProxyApiSplitToCall(taskList, dataConvertFunc, dataSaveFunc, _logger);

  

function作为参数的使用

                Func<List<FacebookDailyReportConvertFromClient>, List<FacebookImpressDeviceReport>> dataConvertFunc = (originalData) => { return DateConvertToDB(originalData, accounts); };
Func<List<FacebookImpressDeviceReport>, bool> dataSaveFunc = (saveDB) => { return SaveReportsToDB(saveDB); };
bool saveResult = ReportOperation<FacebookDailyReportConvertFromClient, FacebookImpressDeviceReport>.ProxyApiSplitToCall(taskList, dataConvertFunc, dataSaveFunc, _logger);

  

泛型抽象类:

    /// <summary>
/// get reoports from proxy client
/// </summary>
/// <typeparam name="RQ">request type</typeparam>
/// <typeparam name="RP">response list type</typeparam>
/// <typeparam name="CRQ">proxy client request type</typeparam>
/// <typeparam name="CRP">proxy client response type</typeparam>
public abstract class ReportDownloadBase<RQ, RP,CRQ,CRP> where RQ : class where RP : class where CRQ : class where CRP : class
{
protected string exportPath;
protected System.Collections.Specialized.NameValueCollection appSettings;
protected ILogBase _logger;
protected string _plantform; public ReportDownloadBase(ILogBase logger,string plantform)
{
_plantform = plantform;
appSettings = WestWin.Common.Configuration.ConfigurationManager.Default.AppSettings;
exportPath = Path.Combine(System.IO.Directory.GetCurrentDirectory(), appSettings["ReportRawPath"], plantform);
_logger = logger;
} /// <summary>
/// Generate ReportRequest for proxy client
/// </summary>
/// <param name="req">request</param>
/// <returns></returns>
protected abstract CRQ GenerateReportRequest(RQ req); /// <summary>
/// Generate Results to return
/// </summary>
/// <param name="resp">ReportResponse</param>
/// <param name="breakdownValue">breakdownValue </param>
/// <returns>result list</returns>
protected abstract List<RP> GenerateResultsByReportResponse(CRP resp, RQ req); /// <summary>
/// get client response from client request
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
protected abstract CRP GetResponseFromRequest(CRQ req); /// <summary>
/// Get Results By Request
/// </summary>
/// <param name="request"></param>
/// <param name="breakdownValue"></param>
/// <returns></returns>
protected List<RP> Process(RQ request,string breakdownValue)
{
try
{
_logger.Info($"{_plantform} GetReport request:{JsonConvert.SerializeObject(request)}");
var req = GenerateReportRequest(request);
_logger.Info($"{_plantform} proxy client request:{JsonConvert.SerializeObject(req)}"); CRP response = null;
int maxTry = ConfigHelper.ApiTryMaxNum;
int count = 0;
while (count < maxTry)
{
count++;
response = null;
try
{
response = GetResponseFromRequest(req);
}
catch (Exception e)
{
_logger.Error($"{_plantform} proxy client get report failed:Round {count}", e);
if(count== maxTry)
{
_logger.Error($"{_plantform} proxy client get report: exception & retry time:{count}", e);
throw e;
}
}
if (response != null) break;
_logger.Warn($"{_plantform} proxy client get report failed:retry Num: {count},request:{JsonConvert.SerializeObject(req)}");
System.Threading.Thread.Sleep(5000); }
if (response == null)
{
return null;
} _logger.Info($"{_plantform} proxy client Get Report sucess:{JsonConvert.SerializeObject(response)}");
var result = GenerateResultsByReportResponse(response, request);
_logger.Info($"{_plantform} return Report result:{JsonConvert.SerializeObject(result)}");
CommandHelper.CreateDictionaryIfNotExists(exportPath);
if (result == null || result.Count == 0)
{
_logger.Warn($"{_plantform} return empty result for request:{JsonConvert.SerializeObject(req)}");
}
else
{
var path = Path.Combine(exportPath, $"{_plantform}-row-{breakdownValue}-{DateTime.Now.ToString("yyyyMMddHHmmss")}-{Guid.NewGuid().ToString()}.csv");
bool saveSucess = CommandHelper.SaveDataToCSVFile<RP>(result, path);
_logger.Info($"{_plantform} report save local file result:{saveSucess}");
}
return result;
}
catch (Exception ex)
{
_logger.Error($"exception. request.request: {JsonConvert.SerializeObject(request)}; request.breakdownValue: {JsonConvert.SerializeObject(breakdownValue)};error:{ex.ToString()}");
throw ex;
}
}
}

  

被使用:

    public class FacebookCountryCmd : ReportDownloadBase<FacebookDailyReportEachRequest, FacebookDailyReportConvertFromClient, FacebookGetAdsInsightRequest, FacebookGetAdsInsightsResponse>, IFacebookCountryCmd
{
IFacebookCountryReportService _facebookCountryReportService;
IFacebookProxyService _FacebookProxyClient;
IAccountCampaignOperation _campaignOperation;
IFacebookCampaignHelper _facebookCampaignHelper;
Platform.Service.Enterprise.AccountChannel _accountChannel = Platform.Service.Enterprise.AccountChannel.Facebook;
Dictionary<string, FacebookSearchAdgeolocationEntity> _countryDic=new Dictionary<string, FacebookSearchAdgeolocationEntity>();
public FacebookCountryCmd(ILogBase logger,
IFacebookCountryReportService facebookCountryReportService, IAccountCampaignOperation campaignOperation,
IFacebookProxyService FacebookProxyClient,IFacebookCampaignHelper facebookCampaignHelper) : base(logger, "facebook")
{
_facebookCountryReportService = facebookCountryReportService;
_FacebookProxyClient = FacebookProxyClient;
_campaignOperation = campaignOperation;
_facebookCampaignHelper = facebookCampaignHelper;
GetAllCountry();
} public List<FacebookCountryReport> DateConvertToDB(List<FacebookDailyReportConvertFromClient> reportDatas, List<BusinessAdsPlatformAccountDetail> accounts)
{
//*****
} public void Execute(FacebookCmdOptions opt)
{
//*****
} public bool SaveReportsToDB(List<FacebookCountryReport> reportDB)
{
//****
} protected override FacebookGetAdsInsightRequest GenerateReportRequest(FacebookDailyReportEachRequest req)
{
//****
} protected override List<FacebookDailyReportConvertFromClient> GenerateResultsByReportResponse(FacebookGetAdsInsightsResponse response, FacebookDailyReportEachRequest req)
{
//***
} protected override FacebookGetAdsInsightsResponse GetResponseFromRequest(FacebookGetAdsInsightRequest req)
{
//****
} private bool IfNextPage(FacebookGetAdsInsightsResponse response, ref FacebookGetAdsInsightRequest request)
{
//****
}
}

  

    public interface IFacebookCountryCmd: IReportCmdBase<FacebookCountryReport, FacebookCmdOptions, FacebookDailyReportConvertFromClient>
{
}

  

    /// <summary>
/// execute download report
/// </summary>
/// <typeparam name="RDB">report type define by DB</typeparam>
/// <typeparam name="CMD">command type</typeparam>
/// <typeparam name="RP">report response including all data get from proxy client</typeparam>
public interface IReportCmdBase<RDB,CMD,RP> where RDB : class where CMD:class where RP:class
{ /// <summary>
/// Save Reports To DB
/// </summary>
/// <param name="reportDB"></param>
/// <returns></returns>
bool SaveReportsToDB(List<RDB> reportDB); /// <summary>
/// convert report to match datebase define
/// </summary>
/// <param name="reportDatas"></param>
/// <returns></returns>
List<RDB> DateConvertToDB(List<RP> reportDatas, List<BusinessAdsPlatformAccountDetail> accounts); /// <summary>
/// Execute Download Report :get from proxy client api & save original data to local file & save to DB
/// </summary>
/// <param name="opt">command</param>
void Execute(CMD opt);
}

  

c# 泛型的应用的更多相关文章

  1. 一起学 Java(三) 集合框架、数据结构、泛型

    一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...

  2. .NET面试题系列[8] - 泛型

    “可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用.“ - Jon Skeet .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] ...

  3. C#4.0泛型的协变,逆变深入剖析

    C#4.0中有一个新特性:协变与逆变.可能很多人在开发过程中不常用到,但是深入的了解他们,肯定是有好处的. 协变和逆变体现在泛型的接口和委托上面,也就是对泛型参数的声明,可以声明为协变,或者逆变.什么 ...

  4. 编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议106~109)

    建议106:动态代理可以使代理模式更加灵活 Java的反射框架提供了动态代理(Dynamic Proxy)机制,允许在运行期对目标类生成代理,避免重复开发.我们知道一个静态代理是通过主题角色(Prox ...

  5. 6.在MVC中使用泛型仓储模式和依赖注入实现增删查改

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...

  6. C#泛型详解(转)

    初步理解泛型: http://www.cnblogs.com/wilber2013/p/4291435.html 泛型中的类型约束和类型推断 http://www.cnblogs.com/wilber ...

  7. C# 泛型

    C# 泛型 1.定义泛型类 在类定义中包含尖括号语法,即可创建泛型类: class MyGenericClass<T> { //Add code } 其中T可以遵循C#命名规则的任意字符. ...

  8. java8中lambda表达式的应用,以及一些泛型相关

    语法部分就不写了,我们直接抛出一个实际问题,看看java8的这些新特性究竟能给我们带来哪些便利 顺带用到一些泛型编程,一切都是为了简化代码 场景: 一个数据类,用于记录职工信息 public clas ...

  9. java 泛型

    1.Student stu =tool.getObj();右边得到的是Object类型,需要向下转型,强转换. 2. 3. 4.泛型方法不能被静态修饰这样写 5.如果想定义定义静态泛型方法,只能这样写 ...

  10. Java泛型的历史

    为什么Java泛型会有当前的缺陷? 之前的章节里已经说明了Java泛型擦除会导致的问题,C++和C#的泛型都是在运行时存在的,难道Java天然不支持“真正的泛型”吗? 事实上,在Java1.5在200 ...

随机推荐

  1. python实现堆栈和队列

    利用python列表实现堆栈和队列 堆栈: 堆栈是一个后进先出的数据结构,其工作方式就像生活中常见到的直梯,先进去的人肯定是最后出. 我们可以设置一个类,用列表来存放栈中的元素的信息,利用列表的app ...

  2. CRM rbac 组件的应用

    1 拷贝 rbac 组件到项目中,注册这个app 2 数据库迁移 1 删除rbac下migrations里除了init外的文件 2 修改用户表 class User(models.Model): &q ...

  3. windows WTL使用命令行参数

    两中方法: 第一种: int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLin ...

  4. 怎样从外网访问内网WebSphere?

    本地安装了一个WebSphere,只能在局域网内访问,怎样从外网也能访问到本地的WebSphere呢?本文将介绍具体的实现步骤. 准备工作 安装并启动WebSphere 默认安装的WebSphere端 ...

  5. kivy 滑动

    from kivy.uix.gridlayout import GridLayout from kivy.app import App from kivy.lang.builder import Bu ...

  6. Python 一些有趣的技巧,包括协程例

    1. 路径操作 比起 os 模块的 path 方法,python3 标准库的 pathlib 模块的 Path 处理起路径更加的容易. ####获取当前文件路径 前提导入 os 和 pathlib 包 ...

  7. django变量使用-在模板中使用视图函数中的变量

    DTL语言,即django template language 第一次使用时,需要修改项目的setting.py文件,将其中TEMPLATES中的DIRS修改为os.path.join(BASE_DI ...

  8. P2590 [ZJOI2008]树的统计(树链剖分)

    P2590 [ZJOI2008]树的统计 虽然是入门树剖模板 但是我终于1A了(大哭) 懒得写啥了(逃 #include<iostream> #include<cstdio> ...

  9. AngularJs 开发遇到的问题,以及解决方案

    1>ng-if 导致 ng-model 失效的问题 比如说下拉联动隐藏显示的时候,多个验证模块,需要使用到ng-if.可以使用 $parent 来解决这个问题 ng-model="$p ...

  10. win7搭建pyqt4开发环境

    版本 win7 64bit python2.7 https://www.python.org/ftp/python/2.7.13/python-2.7.13.amd64.msi pyqt4 https ...