首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用continuation链接任务数组

使用continuation链接任务数组
EN

Stack Overflow用户
提问于 2012-07-01 02:30:31
回答 2查看 730关注 0票数 1

我有一个有点复杂的任务结构(至少对我来说)。它的结构是:

(其中T=任务)

T1,T2,T3...Tn.有一个数组(文件列表),T表示为每个文件创建的任务。每个T总是有两个必须完成或失败的子任务: Tn.1、Tn.2 -下载并安装。对于每个下载(Tn.1),总是有两个子任务可以尝试,从两个路径(Tn.1.1,Tn.1.2)下载。

执行将是:

首先,下载文件: Tn1.1。如果Tn.1.1失败,则Tn.1.2执行。如果download tasks返回OK -执行Tn.2。如果Tn.2已执行或失败-转到下一Tn。

我想要做的第一件事,就是用锯齿数组写出所有这些结构:

代码语言:javascript
复制
    private void CreateTasks()
    {     
        //main array
        Task<int>[][][] mainTask = new Task<int>[_queuedApps.Count][][];
        for (int i = 0; i < mainTask.Length; i++)
        {
            Task<int>[][] arr = GenerateOperationTasks();
            mainTask[i] = arr;
        }
    }

    private Task<int>[][] GenerateOperationTasks()
    {
        //two download tasks 
        Task<int>[] downloadTasks = new Task<int>[2];
        downloadTasks[0] = new Task<int>(() => { return 0; });
        downloadTasks[1] = new Task<int>(() => { return 0; });

        //one installation task 
        Task<int>[] installTask = new Task<int>[1] { new Task<int>(() => { return 0; }) };

        //operations Task is jagged - keeps tasks above
        Task<int>[][] operationTasks = new Task<int>[2][];
        operationTasks[0] = downloadTasks;
        operationTasks[1] = installTask;

        return operationTasks;
    }

因此,现在我得到了任务的mainTask数组,其中包含了如上所述的有序任务。然而,在阅读了ContinuationTasks上的文档后,我意识到这对我没有帮助,因为我必须调用例如Task.ContinueWith(Task2)。对于在我的mainTask数组上执行此操作,我感到困惑。我不能写mainTask.ContinueWith(mainTask1),因为我不知道数组的大小。

如果我能以某种方式引用数组中的下一个任务(但不知道它的索引),但无法弄清楚如何引用。有什么想法吗?非常感谢你的帮助。

致以敬意,

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-01 05:13:34

如果你想在后台线程上按顺序运行一些操作,你不需要很多Task,只需要一个:

代码语言:javascript
复制
Task.Factory.StartNew(DownloadAndInstallFiles)

在该Task中,您可以使用正常的顺序控制流构造,如foreachif来做您想做的事情。类似于:

代码语言:javascript
复制
void DownloadAndInstallFiles()
{
    foreach (var file in files)
    {
       var downloaded = Download(file, primarySource);
       if (downloaded == null)
           downloaded = Download(file, secondarySource);

       if (downloaded != null)
           Install(downloaded);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2012-07-01 04:55:17

如何在要安装的队列应用程序列表上使用并行库?

正如svick在上面的评论中所说的,尝试下载然后安装的过程是非常同步的,所以你不需要为此而需要任务,只需要一些连续的代码。

但是,为了同时下载所有应用程序并并行安装,您可能希望使用您的数据和下载+安装方法来填充应用程序列表,然后使用并行库来并行执行所有应用程序。这里有一个例子,我从你的帖子中猜到了很多东西,但应该能让你对我所说的有所了解。

如果你希望在一个单独的任务中完成整个任务,并在所有应用程序并行下载的同时做其他事情,你可以将并行代码封装在一个任务中,并在代码中的其他地方执行它,继续在其他事情上工作,最后等待任务完成。

这可能是您要下载的每个应用程序的一个类:

代码语言:javascript
复制
/// <summary>
/// Class for each of your apps to be downloaded and installed. You can also
/// derive this in other types of apps that require a different download or install
/// approach.
/// </summary>
class AppToDownload
{
    /// <summary>
    /// The addresses to download this app
    /// </summary>
    public List<string> DownloadAddresses { get; set; }

    /// <summary>
    /// Flag that tells if this task was successfully installed. Set to false
    /// as default.
    /// </summary>
    public bool Installed { get; set; }

    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="downloadAddresses">Addresses to download this app from, they
    /// should be in order of preference</param>
    public AppToDownload(List<string> downloadAddresses)
    {
        this.DownloadAddresses = downloadAddresses;
        this.Installed = false;
    }

    /// <summary>
    /// Public method to be called to Install this app. It will download, and if
    /// successful, will install
    /// </summary>
    /// <returns></returns>
    public bool InstallApp()
    {
        this.Installed = (this.TryDownload() && this.TryInstall());
        return this.Installed;
    }

    /// <summary>
    /// Internal method to download this App. You can override this in a derived
    /// class if you need to.
    /// </summary>
    /// <returns></returns>
    protected virtual bool TryDownload()
    {
        bool res = false;

        // (...) Your code to download, return true if successful

        return res;
    }

    /// <summary>
    /// Internal method to install this App. You can override this in a derived
    /// class if you need to.
    /// </summary>
    /// <returns></returns>
    protected virtual bool TryInstall()
    {
        bool res = false;

        // (...) Your code to install, return true if successful

        return res;
    }
}

下面是并行下载和安装所有应用程序的代码。您还可以使用类ParallelOptions的实例来个性化并行循环的工作方式。

代码语言:javascript
复制
List<AppToDownload> queuedApps = new List<AppToDownload>();

// (...) Fill the list of apps

// Try Install all Apps in parallel
Parallel.ForEach(queuedApps, (app) => app.InstallApp());
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11276610

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档