如何链它的previous实例的任务吗? [英] How to chain a task to a previous instance of it?

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

问题描述

展望链任务到previous举例来说,如果它的存在。目前,两者都在同一时间执行。

初​​始code,对于工作的有一个的任务:

 专用异步无效MenuMediaAddFiles_OnClick(对象发件人,RoutedEventArgs E)
    {
        变种对话框= GetDefaultOpenFileDialog();
        使用(对话)
        {
            如果(dialog.ShowDialog()== System.Windows.Forms.DialogResult.OK)
            {
                使用(VAR进度=新SimpleProgress(本))
                {
                    INT addFiles =等待_context.AddFiles(dialog.FileNames,进度);
                    Console.WriteLine(文件还说:{0},addFiles);
                }
            }
        }
    }

一个失败的尝试,使其工作:

 任务< INT> _FILES;
    私人异步无效MenuMediaAddFiles_OnClick(对象发件人,RoutedEventArgs E)
    {
        变种对话框= GetDefaultOpenFileDialog();
        使用(对话)
        {
            如果(dialog.ShowDialog()== System.Windows.Forms.DialogResult.OK)
            {
                使用(VAR进度=新SimpleProgress(本))
                {
                    INT addFiles;
                    任务< INT>文件= _context.AddFiles(dialog.FileNames,进度);
                    如果(_files == NULL)
                    {
                        _files =文件;
                    }
                    其他
                    {
                        VAR任务1 =等待_files.ContinueWith(任务=> _context.AddFiles(dialog.FileNames,新SimpleProgress(本)));
                    }                    addFiles =等待_FILES;
                    Console.WriteLine(文件还说:{0},addFiles);
                }
            }
        }
    }


解决方案

您为pretty接近,但存在需要修改的几件事情:

 私人任务< INT> previousTask = Task.FromResult(0);
私人异步无效MenuMediaAddFiles_OnClick(对象发件人,RoutedEventArgs E)
{
    变种对话框= GetDefaultOpenFileDialog();
    使用(对话)
    {
        如果(dialog.ShowDialog()== System.Windows.Forms.DialogResult.OK)
        {
            使用(VAR进度=新SimpleProgress(本))
            {
                previousTask = previousTask.ContinueWith(T =>
                    _context.AddFiles(dialog.FileNames,进度))
                    .UnWrap(); ;                INT addFiles =等待previousTask;
                Console.WriteLine(文件还说:{0},addFiles);
            }
        }
    }
}

注意事项:


  • 而不是具有previous任务是有时,它更容易把它初始化为一个已经完成的任务( Task.FromResult(0))。这就避免了空检查code。


  • 您分别致电 AddFiles 的两倍。你不应该在如果调用它,而你没有分配过任务中的如果


  • 我用解开而不是等待打开任务<任务&LT ; INT>> 任务< INT> 。这两个工作,但在这种情况下,我觉得解开做了它的意图更加清晰。


  • 请注意,由于整个事件处理程序将在UI线程上运行就没有必要进行同步访问 previousTask ,如果它不,你需要做一些锁定。


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

A failed attempt to make it work :

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

Things to note:

  • 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.

  • 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.

  • 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.

  • 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.

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

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