我有以下的代码,开始作为一个孩子的任务,以获得给定目录下的所有文件,并做一些事情上的主题和调用事件的每个文件,提醒父任务:等待子任务,真正compelete
internal class FileFinder
{
private readonly string _fileFormat;
public delegate void FileFoundDelegate(string filePath);
public event FileFoundDelegate OnFileFound;
public FileFinder(string fileFormat)
{
_fileFormat = fileFormat;
}
public bool Start(CancellationToken cancellationToken, string directory)
{
try
{
if (OnFileFound == null)
return false;
var foundedFiles = new ThreadLocal<IEnumerable<string>>();
try
{
foundedFiles.Value = Directory.EnumerateFiles(directory, _fileFormat, SearchOption.AllDirectories)
.AsParallel();
}
catch (Exception ex)
{
Debug.WriteLine("Parallel : " + ex.Message);
}
foreach (var file in foundedFiles.Value)
{
if (cancellationToken.IsCancellationRequested)
return true;
// Call file found event with normalized file name
OnFileFound?.Invoke(file);
}
return true;
}
catch (Exception ex)
{
Common.DebugLog(System.Reflection.MethodBase.GetCurrentMethod().Name,
ex.InnerException?.Message ?? ex.Message);
return false;
}
}
}
,并使用名为撒母任务,分散经营的5 seprate任务FileFinder是主题之一调用它:
internal class Scatter
{
private readonly CancellationToken _cancellationToken;
private readonly string _directory;
private readonly string _fileFormat;
private FileFinder _emailFinder;
public Scatter(CancellationToken cancellationToken, string directory, string fileFormat)
{
_cancellationToken = cancellationToken;
_directory = directory;
_fileFormat = fileFormat;
}
public Task Start()
{
try
{
return Task.Factory.StartNew(StartProc,
TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning);
}
catch (Exception)
{
return null;
}
}
private void StartProc()
{
try
{
// Find pdf files
_emailFinder = new FileFinder(_fileFormat);
_emailFinder.OnFileFound += FileFound;
Task.Factory.StartNew(() => _emailFinder.Start(_cancellationToken, _directory),
TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning);
}
catch (Exception ex)
{
Common.DebugLog(System.Reflection.MethodBase.GetCurrentMethod().Name, ex.InnerException.Message);
}
}
private void FileFound(string filePath)
{
Debug.WriteLine("File Found");
}
}
最后一个主任务运行单独分散的每个目录:
internal class Master
{
private readonly CancellationToken _cancellationToken;
internal delegate void ParseFinish();
public event ParseFinish OnParseFinish;
public Master(CancellationToken cancellationToken)
{
_cancellationToken = cancellationToken;
}
public bool Start(List<string> targetDirectories, string fileFormat)
{
try
{
Task.Factory.StartNew(() => StartProc(targetDirectories, fileFormat), _cancellationToken);
return true;
}
catch (Exception ex)
{
Common.DebugLog(System.Reflection.MethodBase.GetCurrentMethod().Name,
ex.InnerException?.Message ?? ex.Message);
return false;
}
}
private bool StartProc(List<string> directories, string fileFormat)
{
try
{
List<Task> targetScatterList = new List<Task>();
foreach (string dir in directories)
{
var scatter = new Scatter(_cancellationToken,dir, fileFormat);
targetScatterList.Add(scatter.Start());
}
// Wait for finish all tasks & call parse finish event
Task.WaitAll(targetScatterList.ToArray());
OnParseFinish?.Invoke();
return true;
}
catch (Exception ex)
{
Common.DebugLog(System.Reflection.MethodBase.GetCurrentMethod().Name,
ex.InnerException?.Message ?? ex.Message);
return false;
}
}
}
我有主任务等待所有目录的任务完成并且不涉及应用程序主线程。从主线程
主任务调用是这样的:
List<string> directoryList = ListBox1.Items.Cast<string>().ToList();
// Create cancelation token
_cancellationTokenSource = new CancellationTokenSource();
_cancellationToken = _cancellationTokenSource.Token;
// Start master task that populate new task for each target
var masterTask= new Master(_cancellationToken);
masterTask.OnParseFinish += ParseFinish;
masterTask.Start(directoryList, tbFileFormat.Text);
我有样书导演287198个PDF文件时,的FileFound事件称为项目(287170,287182,287146和等)的不同的运行随机时间并且不会迭代所有创建的项目。
小文件列表它剂量没有表现出很大的差异
我觉得父任务去完成和孩子立即去杀人。
有什么想法?
谢谢。
:
如果你想知道它何时完成,只是这样做它,你可以做一个'Console.WriteLine(createdFiles.Value.Length)'来确保枚举本身是完整的吗? –
你在你的'StartProc'方法中开始一个任务,不要等待它。你提到你的主线程正在等待父任务,但你的父任务不在等待子任务。 –
@EdT不正确 - 如果子任务以AttachedToParent标志开始,等待父任务只有在所有连接的子任务完成后才会返回。 – Evk