我正在编写一个应用程序,它将数据库中的大量数据导出到具有特定文件结构的文件中。到目前为止只定义了一种“类型”的导出,但会有更多,所以我希望能够轻松插入新的“类型”。 我定义了以下所有导出'类型'必须实现的接口:
public interface IExportService
{
ExportType ExportType { get; set; }
Task DoExport(Store store);
}
ExportType
是枚举,Store
对象是客户(而不是某种数据存储)。
到目前为止,只有一个类实现了这个接口:RetailExportService
。
public class RetailExportService : IExportService
{
public ExportType Type
{
get { return ExportType.Retail; }
}
public async Task DoExport(Store store)
{
List<IRetailExport> retailExports = GetRetailExportFiles();
foreach (var retailExport in retailExports)
{
await retailExport.Export(store);
}
}
private List<IRetailExport> GetRetailExportFiles()
{
return (from t in Assembly.GetExecutingAssembly().GetTypes()
where t.GetInterfaces().Contains(typeof(IRetailExport))
select Activator.CreateInstance(t) as IRetailExport).ToList();
}
}
此类循环遍历程序集中的所有IRetailExport
接口,并调用它的Export
方法。实际查询数据和创建文件是在Export
方法中完成的。
public interface IRetailExport
{
String FileName { get; }
Task Export(Store store);
}
因此,如果必须创建一个新文件,我可以创建一个实现IRetailExport
的新类,这将由应用程序自动调用。
我遇到的问题是我有13个实现IRetailExport
的类,其中5个类需要相同的数据。目前我正在查询每个类中的数据库,但这是一个坏主意并且会降低应用程序的速度。
我能想到的唯一方法就是定义一个这样的界面:
public interface IDataRequired<T> where T: class
{
IEnumerable<T> Data { get; set; }
}
并让类需要相同的数据实现此类。在DoExport()
方法中,我可以检查此类是否实现了IDataRequired - 如果是,则填充Data属性:
public async Task DoExport(Store store)
{
List<IRetailExport> retailExports = GetRetailExportFiles();
List<ExpRmProductIndex> requiredData = await GetIndexedProductList(store.Id);
foreach (var retailExport in retailExports)
{
if (retailExport is IDataRequired<ExpRmProductIndex>)
(retailExport as IDataRequired<ExpRmProductIndex>).Data = requiredData;
await retailExport.Export(store);
}
}
但是,我认为这不是一个非常优雅的解决方案,所以我希望有人能提出更好的方法来解决这个问题吗?谢谢!!
答案 0 :(得分:0)
在并行任务中读取或写入许多文件并不是一个好主意,因为这会使磁盘头在文件之间多次跳转而导致延迟。 (我假设如果循环中有await
,就会发生这种情况。)
相反,按严格的顺序处理一个文件,然后await
一次处理整个过程。