Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

storing the task completion time of every task using Task factory

I am using task factory to spawn parallel threads and my code is as below. I have the requirement to print the completion time of every thread but dont know how to check for every thread. Currently my code is waiting for all tasks to finish and then calculating the time.

stp1.Start();
        for (int i = 0; i < tsk.Length; i++)
        {
            tsk[i] = Task.Factory.StartNew((object obj) =>
            {
                resp = http.SynchronousRequest(web, 443, true, req);
            }, i);
        }
        try
        {
            Task.WaitAll(tsk);
        }
        stp1.Stop();
like image 267
priya Avatar asked Apr 16 '15 07:04

priya


People also ask

What is task completion time?

a measure of the time it takes a user to perform a task (from start to finish). This is a typical metric in usability evaluation.

What is the difference between task run and task factory StartNew?

Task. Run(action) internally uses the default TaskScheduler , which means it always offloads a task to the thread pool. StartNew(action) , on the other hand, uses the scheduler of the current thread which may not use thread pool at all!

What does task factory StartNew do?

StartNew(Action<Object>, Object, CancellationToken, TaskCreationOptions, TaskScheduler) Creates and starts a task for the specified action delegate, state, cancellation token, creation options and task scheduler.

Which threading task method will create a task that will complete when any of the associated tasks have completed?

Wait method. A call to the Wait method blocks the calling thread until the single class instance has completed execution. The following example calls the parameterless Wait() method to wait unconditionally until a task completes. The task simulates work by calling the Thread.


2 Answers

You can add a continuation to the Task. Continuation is a method which will be called when the given Task is completed.

for (int i = 0; i < tsk.Length; i++)
{
    tsk[i] = Task.Factory.StartNew((object obj) =>
    {
        resp = http.SynchronousRequest(web, 443, true, req);
    }, i);

    tsk[i].ContinueWith(antecedent=> 
    {
        //antecedent is completed
        //Do whatever here                
    });
}

If you need to time individual tasks, you need one stopwatch per Task. You can start the StopWatch inside StartNew and stop it in ContinueWith.

If this is your actual code, you can simply time the synchronous operation which you invoke (http.SynchronousRequest in this case). For example following code is enough.

for (int i = 0; i < tsk.Length; i++)
{
    tsk[i] = Task.Factory.StartNew((object obj) =>
    {
        StopWatch watch = StopWatch.StartNew();

        resp = http.SynchronousRequest(web, 443, true, req);

        watch.Stop();
        Console.WriteLine(watch.Elapsed);
    }, i);
}

Btw, Network operations are inherently asynchronous; There will be asynchronous API available, you can use it instead of wrapping a synchronous web request in Task. For instance, maybe HttpClient.SendAsync.

like image 55
Sriram Sakthivel Avatar answered Oct 05 '22 21:10

Sriram Sakthivel


I'd start off by saying that you don't need threadpool threads to execute async IO bound operations. Instead of using Task.Factory.StartNew, use naturally asynchronous API's such as the one HttpClient offers, for example.

Then, i'd say you can use Task.WhenAny to wait on the completion of each of your tasks as they finish:

// Note I'm assuming some kind of async implementation which returns a Task<T>
var tasks = tsk.Select(req => http.AsyncRequest(web, 443, true, req));

while (tasks.Count > 0)
{
    var finishedTask = await Task.WhenAny(tasks);
    // Do something with finishedTask

    tasks.Remove(finishedTask);
}
like image 45
Yuval Itzchakov Avatar answered Oct 05 '22 19:10

Yuval Itzchakov