i was looking for way out run multiple task and report about task status not sequencially.
here i am pasting a code where multiple task running and reporting when all task complete.
var task1 = Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
return "dummy value 1";
});
var task2 = Task.Factory.StartNew(() =>
{
Thread.Sleep(13000);
return "dummy value 2";
});
var task3 = Task.Factory.StartNew(() =>
{
Thread.Sleep(2000);
return "dummy value 3";
});
Task.Factory.ContinueWhenAll(new[] { task1, task2, task3 }, tasks =>
{
foreach (Task<string> task in tasks)
{
Console.WriteLine(task.Result);
}
});
Console.ReadLine();
task1 will take less time and then task3 will complete and last task2 will complete but ContinueWhenAll always showing task1 is completed and then task2 & task3. i want to modify the code in such way as a result which task complete fast that will show first not sequentially. where to change in code. guide please. thanks
UPDATE
var taskp = Task.Factory.StartNew(() =>
{
var task1 = Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
return "Task1 finished";
}).ContinueWith((continuation) => { Console.WriteLine(continuation.Result); });
var task2 = Task.Factory.StartNew(() =>
{
Thread.Sleep(3000);
return "Task2 finished";
}).ContinueWith((continuation) => { Console.WriteLine(continuation.Result); });
var task3 = Task.Factory.StartNew(() =>
{
Thread.Sleep(2000);
return "Task3 finished";
}).ContinueWith((continuation) => { Console.WriteLine(continuation.Result); });
return "Main Task finished";
});
taskp.ContinueWith(t => Console.WriteLine(t.Result));
Console.ReadLine();
An easy solution would be to ContinueWith each task, individually. This is a very quick and dirty example:
var taskp = Task.Factory.StartNew(() =>
{
var task1 = Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
return "dummy value 1";
}).ContinueWith((continuation) => { Console.WriteLine("task1"); });
var task2 = Task.Factory.StartNew(() =>
{
Thread.Sleep(3000);
return "dummy value 2";
}).ContinueWith((continuation) => { Console.WriteLine("task2"); });
var task3 = Task.Factory.StartNew(() =>
{
Thread.Sleep(2000);
return "dummy value 3";
}).ContinueWith((continuation) => { Console.WriteLine("task3"); });
Task.Factory.ContinueWhenAll(new Task[] { task1, task2, task3}, (x) => { Console.WriteLine("Main Task Complete"); });
});
The code is updated to adapt to OP's UPDATE, with a "Main" task which will output after all the "inner" tasks are complete. To make it so taskp returns the string instead of writing it, the code becomes
var taskp = Task.Factory.StartNew<string>(() =>
{
var task1 = ...; //same
var task2 = ...; //same
var task3 = ...; //same
return "Main Task Complete";
}).ContinueWith((x)=> Console.WriteLine(x.Result));
The StartNew<> overload must be used to specify the return type for the Task to have a Result.
Related
I have three tasks like this
public List<CheckResponse> Check(CheckRequest request)
{
var Responses = new List<CheckResponse>();
List<Task> TaskList = new List<Task>();
Task task1 = new Task(() =>
{
Service gatewayObject = new Service();
var response = gatewayObject.Check();
Responses.Add(response);
});
task1.Start();
TaskList.Add(task1);
Task task2 = new Task(() =>
{
Service gatewayObject = new Service();
var response = gatewayObject.Check();
Responses.Add(response);
});
task2.Start();
TaskList.Add(task2);
Task task3 = new Task(() =>
{
Service gatewayObject = new Service();
var response = gatewayObject.Check();
Responses.Add(response);
});
task3.Start();
TaskList.Add(task3);
Task.WaitAll(TaskList.ToArray());
return Responses;
}
Each of them make request to service and can return positive result
so I want to cancel other two task if any of them return positive result.
Service side code is not accessible for me so I can not make any changes on service side.
I have a series of Tasks 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();
}
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.
This is the C# Code
app.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableDetailedErrors = true;
app.MapSignalR(hubConfiguration);
CpuEngine cpuEngine = new CpuEngine(1500);
MemoryEngine memoryEngine = new MemoryEngine(1500);
// Task.Factory.StartNew(async () => await cpuEngine.StartCpuCheck());
// Task.Factory.StartNew(async () => await memoryEngine.StartCheckMemory());
Only the first one is running. How can I run each other?
1) Use Task.Run instead.
2) Remove the keywords async and await in the lambda.
3) Use Task.WhenAll and pass in the two tasks.
public async Task InvokeAsync()
{
var cpuEngine = new CpuEngine(1500);
var memoryEngine = new MemoryEngine(1500);
await Task.WhenAll(
Task.Run(() => cpuEngine.StartCpuCheck()),
Task.Run(() => memoryEngine.StartCheckMemory()));
}
Hello I'm wondering if there is a cleaner way of writing the async code below. Basically I want to wait on all the tasks, but one of the tasks are optional. It feels needlessly elaborate, thinking if I can do it through some callback but haven't been able to figure it out.
var mobile = true;
var task1 = _service.Async1();
var tasks = new List<Task>
{
task1
};
Task<int> task2 = null;
if (!mobile)
{
task2 = _service.Async2();
tasks.Add(task2);
}
await Task.WhenAll(tasks);
var result1 = task1.Result;
if (!mobile)
{
result2 = task2.Result;
// Do stuff
}
There is no need to create a list and await all the results at once. Why not await it when you need it? If task2 runs much longer than task1, you can at least start processing it, long before task2 is done.
Something like this:
var task1 = _service.Async1();
Task<int> task2 = null;
if (!mobile)
{
task2 = _service.Async2();
}
var result1 = await task1;
if (!mobile)
{
var result2 = await task2;
// Do stuff
}
new TaskFactory(TaskScheduler).StartNew(() =>
{
new TaskFactory(TaskScheduler).ContinueWhenAll(
new[] { Task1, Task2,},
completedTasks =>
{
Funct();
});
});
Funct() is getting called before Task1 and Task2 completed