如何将任务链接到它的前一个实例?

时间:2013-04-29 18:21:03

标签: c# .net-4.5 async-await

希望将任务链接到先前的实例(如果存在)。目前,两者都是同时执行的。

适用于一个任务的初始代码:

    private async void MenuMediaAddFiles_OnClick(object sender, RoutedEventArgs e)
    {
        var dialog = GetDefaultOpenFileDialog();
        using (dialog)
        {
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                using (var progress = new SimpleProgress(this))
                {
                    int addFiles = await _context.AddFiles(dialog.FileNames, progress);
                    Console.WriteLine("Files added: {0}", addFiles);
                }
            }
        }
    }

尝试使其无效的尝试失败:

    Task<int> _files;
    private async void MenuMediaAddFiles_OnClick(object sender, RoutedEventArgs e)
    {
        var dialog = GetDefaultOpenFileDialog();
        using (dialog)
        {
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                using (var progress = new SimpleProgress(this))
                {
                    int addFiles;
                    Task<int> files = _context.AddFiles(dialog.FileNames, progress);
                    if (_files == null)
                    {
                        _files = files;
                    }
                    else
                    {
                        var task1 = await _files.ContinueWith(task => _context.AddFiles(dialog.FileNames, new SimpleProgress(this)));
                    }

                    addFiles = await _files;
                    Console.WriteLine("Files added: {0}", addFiles);
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:4)

你非常接近,但有一些事情需要修改:

private Task<int> previousTask = Task.FromResult(0);
private async void MenuMediaAddFiles_OnClick(object sender, RoutedEventArgs e)
{
    var dialog = GetDefaultOpenFileDialog();
    using (dialog)
    {
        if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            using (var progress = new SimpleProgress(this))
            {
                previousTask = previousTask.ContinueWith(t =>
                    _context.AddFiles(dialog.FileNames, progress))
                    .UnWrap(); ;

                int addFiles = await previousTask;
                Console.WriteLine("Files added: {0}", addFiles);
            }
        }
    }
}

注意事项:

  • 有时将上一个任务设为null,而不是将其初始化为已完成的任务(Task.FromResult(0))。这避免了空检查代码。

  • 您曾两次致电AddFiles。您不应该在if之前调用它,并且您没有将任务分配给if中的实例字段。

  • 我使用UnWrap代替awaitTask<Task<int>>变为Task<int>。两者都有效,但在这种情况下,我觉得UnWrap使其意图更清晰。

  • 请注意,由于整个事件处理程序将在UI线程中运行,因此无需同步previousTask的访问权限,如果没有,则需要进行一些锁定。