【发布时间】:2013-12-05 18:57:58
【问题描述】:
我想在 C# 中处理子目录和文件的文件系统/文件夹。我正在使用 TPL 库中的任务。这个想法是递归地执行它并为每个文件夹创建一个任务。主线程应该等待子线程完成,然后打印一些信息。事实上,我只想知道扫描何时完成。我从线程池开始,然后切换到 TLP。做了一些简单的例子。经过从简单代码到越来越臃肿的代码的一些尝试后,我被困在这里:
private Logger log = LogManager.GetCurrentClassLogger();
public MediaObjectFolder MediaObjectFolder { get; set; }
private Queue<MediaObjectFolder> Queue { get; set; }
private object quelock, tasklock;
private List<Task> scanTasks;
public IsoTagger()
{
quelock = new object();
tasklock = new object();
scanTasks = new List<Task>();
MediaObjectFolder = new MediaObjectFolder(@"D:\Users\Roman\Music\Rock\temp");
Queue = new Queue<MediaObjectFolder>();
}
public MediaObject RescanFile(string fullpath, string filename)
{
return new MediaObject(fullpath);
}
public void Rescan()
{
Queue.Clear();
lock (tasklock)
{
Task scanFolderTask = Task.Factory.StartNew(ScanFolder, MediaObjectFolder);
scanTasks.Add(scanFolderTask);
}
Task.Factory.ContinueWhenAll(scanTasks.ToArray(), (ant) =>
{
if (log != null)
{
log.Debug("scan finished");
log.Debug("number of folders: {0}", Queue.Count);
}
});
}
private void ScanFolder(object o)
{
List<Task> subTasks = new List<Task>();
MediaObjectFolder mof = o as MediaObjectFolder;
log.Debug("thread - " + mof.Folder);
string[] subdirs = Directory.GetDirectories(mof.Folder);
string[] files = Directory.GetFiles(mof.Folder, "*.mp3");
foreach(string dir in subdirs)
{
log.Debug(dir);
MediaObjectFolder tmp = new MediaObjectFolder(dir);
lock (tasklock)
{
Task tmpTask = new Task(ScanFolder, tmp);
subTasks.Add(tmpTask);
}
}
foreach (Task tsk in subTasks)
{
tsk.Start();
}
foreach (string file in files)
{
log.Debug(file);
MediaObject tmp = new MediaObject(file);
MediaObjectFolder.MediaObjects.Add(tmp);
}
lock (quelock)
{
Queue.Enqueue(mof);
}
if (subTasks != null)
Task.Factory.ContinueWhenAll(subTasks.ToArray(), logTask => log.Debug("thread release - " + mof.Folder));
}
主线程有时仍然过早地继续,而不是在完成所有其他线程之后。 (我对 C# 比较陌生,也不是并行编程方面的专家,所以可能存在一些重量级概念错误)
【问题讨论】:
标签: c# .net multithreading task-parallel-library