AKADER AKADER - 1 month ago 5
C# Question

How can a series of Tasks be made to run in order?

I have a series of

Task
s that I want to run in order from a-z.

I would like to execute these calls synchronously
starting from 1 and ending at N
.


  • task1 DeleteSubProjects...1


    • task1 DeleteActivities...2


      • task1 DeleteActivityPersons...3

      • task2 DeleteThreads...4


        • task1 DeleteCommunicationThreadContentTags...5

        • task2 DeleteCommunicationThreadParticipants...6

        • task3 DeleteMessages

        • task4 Delete(communicationThread)


      • task3 DeleteActivityDocuments

      • task4 DeleteActivityNotes

      • task5 DeleteActivityMachines

      • task6 DeleteActivityLinks

      • task7 DeleteActivityLinks

      • task8 Delete(activity)


    • task2 DeleteSubProjectDocuments

    • task3 DeleteSubProjectNotes

    • task4 DeleteSubProjectPersons

    • task5 DeleteSubProjects

    • task6 Delete(subProject)


  • task2 deleteProjectNotes

  • task3 deleteProjectDocuments

  • task4 deleteActivities

  • task5 deleteProjectPersons



here is what the code looks like

public async Task DeleteProject(Project project)
{

var deleteSubProjects = UnitOfWork.Instance.SubProjectService.DeleteSubProjects(project.SubProjects);
var deleteProjectNotes = UnitOfWork.Instance.ProjectNoteService.DeleteProjectNotes(project.ProjectNotes);
var deleteProjectDocuments = UnitOfWork.Instance.ProjectDocumentService.DeleteProjectDocuments(project.ProjectDocuments);
var deleteActivities = UnitOfWork.Instance.ActivityService.DeleteActivities(project.Activities);
var deleteProjectPersons = UnitOfWork.Instance.ProjectPersonService.DeleteProjectPersons(project.ProjectPersons);

await Task.WhenAll(deleteSubProjects)
.ContinueWith(_ => deleteProjectNotes)
.ContinueWith(_ => deleteProjectDocuments)
.ContinueWith(_ => deleteActivities)
.ContinueWith(_ => deleteProjectPersons)
.ContinueWith(_ => Delete(project)).Unwrap();
}


subprojects

public async Task DeleteSubProjects(IList<SubProject> subProjects)
{
foreach (var subProject in subProjects.ToList())
{
await DeleteSubProject(subProject);
}
}
public async Task DeleteSubProject(SubProject subProject)
{
var task1 = UnitOfWork.Instance.ActivityService.DeleteActivities(subProject.Activities);
var task2 = UnitOfWork.Instance.SubProjectDocumentService.DeleteSubProjectDocuments(subProject.SubProjectDocuments);
var task3 = UnitOfWork.Instance.SubProjectNoteService.DeleteSubProjectNotes(subProject.SubProjectNotes);
var task4 = UnitOfWork.Instance.SubProjectPersonService.DeleteSubProjectPersons(subProject.SubProjectPersons);
var task5 = DeleteSubProjects(subProject.ChildSubProjects);
var task6 = Delete(subProject);

await Task.WhenAll(task1)
.ContinueWith(_ => task2)
.ContinueWith(_ => task3)
.ContinueWith(_ => task4)
.ContinueWith(_ => task5)
.ContinueWith(_ => task6).Unwrap();
//Delete(subProject);
}


activities

public async Task DeleteActivities(IList<Activity> activities)
{
foreach (var activity in activities)
{
await DeleteActivity(activity);
}
}
public async Task DeleteActivity(Activity activity)
{
var task1 = UnitOfWork.Instance.ActivityPersonService.DeleteActivityPersons(activity.ActivityPersons);
var task2 = UnitOfWork.Instance.CommunicationThreadService.DeleteThreads(activity.CommunicationThreads);
var task3 = UnitOfWork.Instance.ActivityDocumentService.DeleteActivityDocuments(activity.ActivityDocuments);
var task4 = UnitOfWork.Instance.ActivityNoteService.DeleteActivityNotes(activity.ActivityNotes);
var task5 = UnitOfWork.Instance.ActivityMachineService.DeleteActivityMachines(activity.ActivityMachines);
var task6 = UnitOfWork.Instance.ActivityLinkService.DeleteActivityLinks(activity.SuccActivityLinks);
var task7 = UnitOfWork.Instance.ActivityLinkService.DeleteActivityLinks(activity.PredActivityLinks);
var task8 = Delete(activity);

await Task.WhenAll(task1)
.ContinueWith(_ => task2)
.ContinueWith(_ => task3)
.ContinueWith(_ => task4)
.ContinueWith(_ => task5)
.ContinueWith(_ => task6)
.ContinueWith(_ => task7)
.ContinueWith(_ => task8).Unwrap();
// Delete(activity);
}


threads

internal async Task DeleteThreads(IList<CommunicationThread> threads)
{
foreach (var thread in threads)
{
await DeleteThread(thread);
}
}
internal async Task DeleteThread(CommunicationThread communicationThread)
{
var task1 = UnitOfWork.Instance.CommunicationThreadContentTagService.DeleteCommunicationThreadContentTags(communicationThread.CommunicationThreadContentTags);
var task2 = UnitOfWork.Instance.CommunicationThreadParticipantService.DeleteCommunicationThreadParticipants(communicationThread.CommunicationThreadParticipants);
var task3 = UnitOfWork.Instance.CommunicationMessageService.DeleteMessages(communicationThread.CommunicationMessages.Where(msg => msg.CommentOnMessageID == null).ToList());
var task4 = Delete(communicationThread);

await Task.WhenAll(task1)
.ContinueWith(_ => task2)
.ContinueWith(_ => task3)
.ContinueWith(_ => task4).Unwrap();
}

Answer

Rather than calling Task.WhenAll and declaring a variable for each Task, simply await each one in the order you need -- for example:

public async Task DeleteProject(Project project)
{
    var instance = UnitOfWork.Instance;

    await instance.SubProjectService.DeleteSubProjects(project.SubProjects);
    await instance.ProjectNoteService.DeleteProjectNotes(project.ProjectNotes);
    await instance.ProjectDocumentService.DeleteProjectDocuments(project.ProjectDocuments);
    await instance.ActivityService.DeleteActivities(project.Activities);
    await instance.ProjectPersonService.DeleteProjectPersons(project.ProjectPersons);          
}

Now the order of the delete operations in this specific example are serialized.