如何将任务链接到它的前一个实例? [英] How to chain a task to a previous instance of it?

查看:18
本文介绍了如何将任务链接到它的前一个实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

希望将任务链接到前一个实例(如果存在).目前,两者同时执行.

Looking to chain a task to a previous instance if it exists. Currently, both are executed at the same time.

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

Initial code that works for one task :

    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);
                }
            }
        }
    }

推荐答案

你已经很接近了,但有一些需要修改的地方:

You were pretty close, but there were a few things that needed to be modified:

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)).这避免了空检查代码.

  • Rather than having the previous task be null sometimes, it was easier to initialize it to an already completed task (Task.FromResult(0)). This avoids the null check code.

您调用了两次 AddFiles.您不应该在 if 之前调用它,并且您从未将任务分配给 if 中的实例字段.

You were calling AddFiles twice. You shouldn't have been calling it before the if, and you weren't ever assigning the task to the instance field inside the if.

我使用 UnWrap 而不是 awaitTask> 转换为 Task<;int>.两者都有效,但在这种情况下,我觉得 UnWrap 使其意图更清晰.

I used UnWrap instead of await to turn the Task<Task<int>> into a Task<int>. Both work, but in this case I felt UnWrap made its intentions clearer.

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

Note that since the entire event handler will be running in the UI thread there's no need to synchronize access to previousTask, if it doesn't, you'd need to do some locking.

这篇关于如何将任务链接到它的前一个实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆