泛型静态类 & 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. superblock 区块数据读取

    鸟哥私房菜笔记: 命令:df -Th Filesystem:代表该文件系统是在哪个 partition ,所以列出设备名称:1k-blocks:说明下面的数字单位是 1KB 呦!可利用 -h 或 -m ...

  2. 设计模式之Proxy(代理)(转)

    理解并使用设计模式,能够培养我们良好的面向对象编程习惯,同时在实际应用中,可以如鱼得水,享受游刃有余的乐趣. Proxy是比较有用途的一种模式,而且变种较多,应用场合覆盖从小结构到整个系统的大结构,P ...

  3. mac电脑复制粘贴使用command+c command+v

    mac电脑复制粘贴使用command+c command+v系统偏好设置--键盘--修饰键(右下角),将ctrl键和command键的功能对换一下即可用ctrl+c ctrl+v复制粘贴缺点:所有的c ...

  4. 3、CentOS 6.5系统安装配置Tomcat 8详细过程

    安装环境:CentOS-6.5 安装方式:源码安装 软件:apache-tomcat-8.0.0.RC3.tar.gz 安装前提 安装tomcat 将apache-tomcat-8.0.0.RC3.t ...

  5. linux--- sort,uniq,cut,wc命令

    1.sort [-fbMnrtuk] [file or stdin] -f :忽略大小写的差异,例如 A 与 a 视为编码相同: -b :忽略最前面的空格符部分: -M :以月份的名字来排序,例如 J ...

  6. redis的常用命令01

    启动redis的命令: redis-server redis.windows.conf把redis设置成windows下的服务的命令:输入命令后刷新会出现redis的服务:redis-server - ...

  7. mycat高可用集群搭建

    本文来源于:https://blog.csdn.net/u012758088/article/details/78741567 Mycat 本身是无状态的,可以用 HAProxy 或四层交换机等设备组 ...

  8. 关于nginx配置虚拟主机

    前提:我的虚拟主机的外网ip为111.231.226.228(是云服务器哈)     本地测试环境为windows7(修改本地的hosts文件) 步骤:(安装nginx可以看看我文章“linux ng ...

  9. 使用nosql实现页面静态化的一个小案列

    页面静态化,其实就是将动态生成的php页面,变成静态的HTML页面,让用户直接访问.有一下几方面好处: 1,首先就是访问速度,不需要去访问数据库,或者缓存来获取哪些数据,浏览器直接加载渲染html页即 ...

  10. 关于scrapy下载文件重命名的办法以及对应url没有文件后缀的办法

    https://www.jianshu.com/p/d1bb28cbb6a8 scrapy中负责下载文件的是class MyFilesPipeline(FilesPipeline)类 其中负责下载文件 ...