【问题标题】:asp.net Program execution continues before tasks finish executingasp.net 程序执行在任务完成执行之前继续
【发布时间】:2018-02-28 15:55:11
【问题描述】:

我正在尝试在不同的线程上运行 3 个任务(还会添加一些。)被调用的任务然后调用其他异步/等待任务。

在我的命令等待后程序继续执行。执行需要等到所有任务完成。我的代码在下面(空返回只是为了测试,我仍然需要创建返回代码。

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 年的 Web 开发。)

在所有任务完成之前,我需要做什么才能停止执行?我尝试了其他一些方法,例如小时候依恋,但我所做的似乎没有任何效果。

编辑 - 我一直在尝试直接从 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 调试器有关吗?

【问题讨论】:

  • 您实际上并没有在等待孩子们。您实际上应该使用await,并在任何地方使用它。
  • 但我希望孩子们在不同的线程上运行
  • await Task.WhenAll(...Task.Run...)

标签: c# asp.net multithreading async-await task-parallel-library


【解决方案1】:

你的代码有很多问题:

  1. 如果您不等待文件被复制,接下来的代码行应该如何运行?
  2. 为什么需要创建TaskFactory来启动后台工作,而这已经是Task
  3. 为什么要创建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;

    ...
}

有一篇关于 async/await 的精彩文章:@StephenCleary 的Async/Await - Best Practices in Asynchronous Programming

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    • 2014-01-28
    • 2016-08-31
    • 1970-01-01
    相关资源
    最近更新 更多