使用Parallels或Async的C#控制台应用程序

时间:2012-11-07 20:34:15

标签: c# .net asynchronous windows-services parallels

有很多例子和关于平行,并发和现在使用.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类,但我们目前希望降低复杂性。控制台应用程序现在更容易调试,并希望解决第一个性能问题。一旦它以最高速度执行,我们总是可以返回并将我们的控制台应用程序包装在服务中。如果可能的话,将此应用程序与平行线或某种类型的多线程相结合,可以使服务更容易转换,因为可能需要这样做。

1 个答案:

答案 0 :(得分:1)

您可以尝试这样的事情:

Parallel.ForEach(filePaths, file =>
    {
        var xmlDoc = XDocument.Load(file);
        if (xmlDoc != null)
        {
            Engine.ProcessXML(xmlDoc);
        }
    });

但是,Engine.ProcessXML()函数可能是也可能不是线程安全的;没有看到代码就无法分辨。