我正在尝试在不同的线程上运行3个任务(还会添加一些任务。)被调用的任务然后调用异步/等待的其他任务。
我的命令等待后程序继续执行。执行需要等到所有任务完成。我的代码如下(null返回只是测试,我仍然需要创建返回代码。
public List<string> CopyFilesAsync(List<ModelIterationModel> model)
{
var copyFileTaskParameters = GetCopyFileTaskParameters(model);
Task<List<CopyFitDataResult>> fitDataResulLits = null;
Task<List<CopyNMStoreResult>> nmStoreResultsList = null;
Task<List<CopyDecompAnalyzerResult>> decompAnalyzerStoreResultsList = null;
Task parent = Task.Factory.StartNew(() =>
{
var cancellationToken = new CancellationToken();
TaskFactory factory = new TaskFactory(TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously);
factory.StartNew(() => fitDataResulLits = CopyFitDataFiles(copyFileTaskParameters, cancellationToken));
factory.StartNew(() => decompAnalyzerStoreResultsList = CopyDecompAnalyzerFiles(copyFileTaskParameters, cancellationToken));
factory.StartNew(() => nmStoreResultsList = CopyNMStoreResultsFiles(copyFileTaskParameters, cancellationToken));
});
parent.Wait();
return null;
}
调用代码是同步的。在完成上述任务之前,在此方法中继续执行。
public void CreateConfigFile(CreateConfigFileParameter parameter)
{
try
{
//data for this will need to come from UI, return values will include local file paths. All copy operations will be ran on it's own thread
//return value will include local file paths
var userFileListModel = _copyFilesToLocalDirectoryService.CopyFilesAsync(temp);
//will return object graph of data read from speadsheets and excel files
_readLocalFilesToDataModelService.ReadAllFiles();
//will take object graph and do date period logic and event type compression and any other business
//logic to extract an object model to create the config file
_processDataModelsToCreateConfigService.Process();
//will take extracted object model and use config file template to create the config file workbook
_writeConfigFileService.WriteConfigFile();
}
catch(Exception ex)
{
}
}
此代码位于WPF应用程序的类库中。我不知道这是否重要,但这是我第一次与WPF进行互动(仅限15年的网络开发。)
在完成所有任务之前,我需要做什么才能停止执行?我玩了一些其他的方法,比如作为孩子附上,但我做的一切似乎都没有。
编辑 - 我一直在尝试直接从MSDN样本中获取方法而没有任何运气。刚试过这个
var cancellationToken = new CancellationToken();
var tasks = new List<Task>();
tasks.Add(Task.Run(() =>
{
fitDataResulLits = CopyFitDataFiles(copyFileTaskParameters, cancellationToken);
}));
Task t = Task.WhenAll(tasks.ToArray());
t.Wait();
与MSDN样本完全一样,我尝试了WaitAll,但它正好经过它 这可能与Visual Studio调试器有关吗?
答案 0 :(得分:1)
您的代码有很多问题:
TaskFactory
来开始后台工作,这已经是Task
了?CancellationToken
?您需要创建一个CancellationTokenSource
,并使用Token
代码取消您可能需要取消的所有代码。此外,此代码:
tasks.Add(Task.Run(() =>
{
fitDataResulLits = CopyFitDataFiles(copyFileTaskParameters, cancellationToken);
}));
不会触发CopyFitDataFiles
,它只是分配任务引用。你需要这样做:
tasks.Add(CopyFitDataFiles(copyFileTaskParameters, cancellationToken));
您的代码应该以这种方式重写:
public async Task<List<string>> CopyFilesAsync(List<ModelIterationModel> model)
{
var copyFileTaskParameters = GetCopyFileTaskParameters(model);
// do not await tasks here, just get the reference for them
var fitDataResulLits = CopyFitDataFiles(copyFileTaskParameters, cancellationToken);
// ...
// wait for all running tasks
await Task.WhenAll(copyFileTaskParameters, ...);
// now all of them are finished
}
// note sugnature change
public async Task CreateConfigFile
{
// if you really need to wait for this task after some moment, save the reference for task
var userFileListModel = _copyFilesToLocalDirectoryService.CopyFilesAsync(temp);
...
// now await it
await userFileListModel;
...
}
@StephenCleary有一篇很棒的关于async / await的文章:Async/Await - Best Practices in Asynchronous Programming