public static IEnumerable <string> SafeEnumerateFileAndDirNames(this string path, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth)
    {
        var searchQueue = new Queue <string>()
        {
            path
        };

        while (searchQueue.Count > 0)
        {
            var cdn = searchQueue.Dequeue();

            IEnumerable <string> cdiFiles = null;
            if (returnOpt.HasFlag(ReturnOptions.ReturnFiles))
            {
                try {
                    cdiFiles = Directory.EnumerateFiles(cdn, filePattern, SearchOption.TopDirectoryOnly);
                }
                catch (Exception) {
                }

                if (cdiFiles != null)
                {
                    foreach (var filename in cdiFiles)
                    {
                        yield return(filename);
                    }
                }
            }

            if ((!returnOpt.HasFlag(ReturnOptions.ReturnFiles) || cdiFiles != null) && (returnOpt.HasFlag(ReturnOptions.ReturnDirectories) || searchOpt == SearchOption.AllDirectories))       // skip if file enumeration failed
            {
                IEnumerable <string> cdiDirs = null;
                try {
                    cdiDirs = Directory.EnumerateDirectories(cdn, dirPattern, SearchOption.TopDirectoryOnly);
                }
                catch (Exception) {
                }

                if (cdiDirs != null)
                {
                    foreach (var dirname in cdiDirs)
                    {
                        if (searchOpt == SearchOption.AllDirectories)
                        {
                            searchQueue.Enqueue(dirname);
                        }

                        if (returnOpt.HasFlag(ReturnOptions.ReturnDirectories))
                        {
                            yield return(dirname);
                        }
                    }
                }
            }
        }
    }
    public static IEnumerable <FileSystemInfo> SafeEnumerateFileSystemInfos(this DirectoryInfo di, string filePattern, string dirPattern, SearchOption searchOpt = SearchOption.TopDirectoryOnly, ReturnOptions returnOpt = ReturnOptions.ReturnBoth)
    {
        var searchQueue = new Queue <DirectoryInfo>();

        searchQueue.Enqueue(di);
        while (searchQueue.Count > 0)
        {
            var cdi = searchQueue.Dequeue();

            IEnumerable <string> cdiFiles = null;
            if (returnOpt.HasFlag(ReturnOptions.ReturnFiles))
            {
                try {
                    cdiFiles = Directory.EnumerateFiles(cdi.FullName, filePattern, SearchOption.TopDirectoryOnly);
                }
                catch (Exception) {
                }

                if (cdiFiles != null)
                {
                    var cfis = new ConcurrentBag <FileInfo>();
                    cdiFiles.AsParallel()
                    .ForAll(f => {
                        try {
                            cfis.Add(new FileInfo(f));
                        }
                        catch (Exception) {
                        }
                    });

                    foreach (var fi in cfis)
                    {
                        yield return(fi);
                    }
                }
            }

            if ((!returnOpt.HasFlag(ReturnOptions.ReturnFiles) || cdiFiles != null) && (returnOpt.HasFlag(ReturnOptions.ReturnDirectories) || searchOpt.HasFlag(SearchOption.AllDirectories)))       // skip if file enumeration failed
            {
                IEnumerable <string> cdiDirs = null;
                try {
                    cdiDirs = Directory.EnumerateDirectories(cdi.FullName, dirPattern, SearchOption.TopDirectoryOnly);
                }
                catch (Exception) {
                }

                if (cdiDirs != null)
                {
                    var cdis = new ConcurrentBag <DirectoryInfo>();
                    cdiDirs.AsParallel()
                    .ForAll(d => {
                        try {
                            cdis.Add(new DirectoryInfo(d));
                        }
                        catch (Exception) {
                        }
                    });
                    foreach (var rdi in cdis)
                    {
                        if (returnOpt.HasFlag(ReturnOptions.ReturnDirectories))
                        {
                            yield return(rdi);
                        }
                        if (searchOpt == SearchOption.AllDirectories)
                        {
                            searchQueue.Enqueue(rdi);
                        }
                    }
                }
            }
        }
    }