我有一个有点复杂的任务结构(至少对我来说)。它的结构是:
(其中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。
我想要做的第一件事,就是用锯齿数组写出所有这些结构:
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),因为我不知道数组的大小。
如果我能以某种方式引用数组中的下一个任务(但不知道它的索引),但无法弄清楚如何引用。有什么想法吗?非常感谢你的帮助。
致以敬意,
发布于 2012-07-01 05:13:34
如果你想在后台线程上按顺序运行一些操作,你不需要很多Task,只需要一个:
Task.Factory.StartNew(DownloadAndInstallFiles)在该Task中,您可以使用正常的顺序控制流构造,如foreach和if来做您想做的事情。类似于:
void DownloadAndInstallFiles()
{
foreach (var file in files)
{
var downloaded = Download(file, primarySource);
if (downloaded == null)
downloaded = Download(file, secondarySource);
if (downloaded != null)
Install(downloaded);
}
}发布于 2012-07-01 04:55:17
如何在要安装的队列应用程序列表上使用并行库?
正如svick在上面的评论中所说的,尝试下载然后安装的过程是非常同步的,所以你不需要为此而需要任务,只需要一些连续的代码。
但是,为了同时下载所有应用程序并并行安装,您可能希望使用您的数据和下载+安装方法来填充应用程序列表,然后使用并行库来并行执行所有应用程序。这里有一个例子,我从你的帖子中猜到了很多东西,但应该能让你对我所说的有所了解。
如果你希望在一个单独的任务中完成整个任务,并在所有应用程序并行下载的同时做其他事情,你可以将并行代码封装在一个任务中,并在代码中的其他地方执行它,继续在其他事情上工作,最后等待任务完成。
这可能是您要下载的每个应用程序的一个类:
/// <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的实例来个性化并行循环的工作方式。
List<AppToDownload> queuedApps = new List<AppToDownload>();
// (...) Fill the list of apps
// Try Install all Apps in parallel
Parallel.ForEach(queuedApps, (app) => app.InstallApp());https://stackoverflow.com/questions/11276610
复制相似问题