如何简化和优化此C#代码

时间:2014-11-26 13:06:36

标签: c# performance optimization foreach

我有这样的方法:

public ConcurrentBag<FileModel> GetExceptionFiles(List<string> foldersPath, List<string> someList)
{
    for (var i = 0; i < foldersPath.Count; i++)
    {
        var index = i;

        new Thread(delegate()
        {
            foreach (var file in BrowseFiles(foldersPath[index]))
            {
                if (file.Name.Contains(someList[0]) || file.Name.Contains(someList[1]))
                {
                    using (var fileStream = File.Open(file.Path, FileMode.Open))
                    using (var bufferedStream = new BufferedStream(fileStream))
                    using (var streamReader = new StreamReader(bufferedStream))
                    ...

为您提供更多详情:

此方法启动n个线程(= foldersPath.Count),每个线程将读取包含someList中列出的字符串的所有文件。

现在我的列表只包含2个字符串(条件),这就是我在做的原因:

file.Name.Contains(someList[0]) || file.Name.Contains(someList[1])

我现在要做的是用检查列表someList

中所有元素的内容替换此行

我该怎么做?

Edit

现在我用 if替换了那行(someList.Any(item =&gt; file.Name.Contains(item)))

接下来的问题是如何优化此代码的性能,知道foldersPath中的每个项目都是我网络中的单独硬盘驱动器(总是不超过5个硬盘驱动器)。

2 个答案:

答案 0 :(得分:3)

您可以使用if (someList.Any(item => file.Name.Contains(item)))

之类的内容

这将迭代someList中的每个项目,并检查文件名中是否包含任何项目,返回一个布尔值以指示是否找到任何匹配项

答案 1 :(得分:1)

Fristly。

有句老话是计算机科学,&#34; CS,命名,缓存失效和关闭一个错误都有两个难题。&#34;

不要使用for循环,除非你绝对必须,你获得的微小性能增益不值得调试时间(假设此版本的.net中有任何性能增益) )。

其次

new Thread。不要这样做。线程的创建非常缓慢并占用大量资源,特别是对于像这样的短期过程。除此之外,在线程之间传递数据存在开销。如果必须使用短期线程,请使用ThreadPool.QueueUserWorkItem(WaitCallback)

然而,正如我之前提到的那样。线程是CPU资源的抽象。老实说,我怀疑你是CPU限制的。线程会比你想象的花费更多。坚持单线程。但是,您受I / O限制,因此请充分利用异步I / O.

public async Task<IEnumerable<FileModel>> GetExceptionFiles(List<string> foldersPath, List<string> someList)
{
    foreach (var folderPath in foldersPath)        
    foreach (var file in BrowseFiles(folderPath))
    {
         if (false == someList.Any(x => file.Name.Contains(x, StringComparer.InvariantCultureCaseIgnore)))
             continue;
         using (var fileStream = await File.OpenTaskAsync(file.Path, FileMode.Open))
         using (var bufferedStream = new BufferedStream(fileStream))
         using (var streamReader = new StreamReader(bufferedStream))
         ...
             yield return new FileModel();