有很多例子和关于平行,并发和现在使用.NET 4.5的异步调用的讨论。我们正在为我们的应用寻找最佳解决方案,因为很多这样的讨论让我们感到困惑。
我们有一个控制台应用程序需要每分钟运行一次,它目前检查目录中的XML文件,然后如果存在,它会同步遍历每个文件,将每个文件作为XMLDocument加载,使用LINQ和List对象解析它然后将其保存到数据库。 XML文件相对较小,最大的可能是400kb,大多数在20-85kb范围内。
我们正在尝试确定最佳路由性能,因为有时会有30-50个文件,运行时间超过一分钟,将其推入需要再次运行的时间。当前正在同步处理文件时,似乎有机会更快地处理它们,因为每个文件都独立于其他文件,但不确定这里有关于线程安全性和性能的最佳方法。
这是我们的代码,我拿出一堆东西来保留主要组件以保持简单。 Engine.ProcessXML是对另一个确定文档类型的方法的调用,然后调用适当的LINQ解析方法和数据库层方法进行保存。
string feedsDir = ConfigHelper.FeedsDirectory;
if (Directory.Exists(feedsDir))
{
//get full xml file paths
string[] filePaths = Directory.GetFiles(feedsDir, "*.xml");
//get total number of files to be processed
int fileCount = filePaths.Length;
if (fileCount > 0)
{
//loop through each file to process
foreach (string file in filePaths)
{
if (File.Exists(file))
{
//load the file into xml document object
XDocument xmlDoc = XDocument.Load(file);
//if xml document not empty, process
if (xmlDoc != null)
{
//parse and save document data
Engine.ProcessXML(xmlDoc);
}
}
}
}
}
附注:我们已经研究过创建一个Windows服务和一些FileSystemWatcher类,但我们目前希望降低复杂性。控制台应用程序现在更容易调试,并希望解决第一个性能问题。一旦它以最高速度执行,我们总是可以返回并将我们的控制台应用程序包装在服务中。如果可能的话,将此应用程序与平行线或某种类型的多线程相结合,可以使服务更容易转换,因为可能需要这样做。
答案 0 :(得分:1)
您可以尝试这样的事情:
Parallel.ForEach(filePaths, file =>
{
var xmlDoc = XDocument.Load(file);
if (xmlDoc != null)
{
Engine.ProcessXML(xmlDoc);
}
});
但是,Engine.ProcessXML()
函数可能是也可能不是线程安全的;没有看到代码就无法分辨。